forked from OSchip/llvm-project
Revert "Revert r301742 which made ExprConstant checking apply to all full-exprs."
This reverts commit r305239 because it broke the buildbots (the diag-flags.cpp test is failing). llvm-svn: 305287
This commit is contained in:
parent
ba6a10fdcc
commit
bec724cbb0
|
@ -10273,7 +10273,6 @@ private:
|
|||
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
|
||||
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
|
||||
void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
|
||||
void CheckForIntOverflow(Expr *E);
|
||||
void CheckUnsequencedOperations(Expr *E);
|
||||
|
||||
/// \brief Perform semantic checks on a completed expression. This will either
|
||||
|
|
|
@ -6226,6 +6226,10 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
|
|||
// the initializer list.
|
||||
ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
|
||||
const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
|
||||
if (Init->isValueDependent()) {
|
||||
Success = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Temporarily override This, in case there's a CXXDefaultInitExpr in here.
|
||||
ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
|
||||
|
@ -9936,7 +9940,8 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
|
|||
}
|
||||
|
||||
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
|
||||
const ASTContext &Ctx, bool &IsConst) {
|
||||
const ASTContext &Ctx, bool &IsConst,
|
||||
bool IsCheckingForOverflow) {
|
||||
// Fast-path evaluations of integer literals, since we sometimes see files
|
||||
// containing vast quantities of these.
|
||||
if (const IntegerLiteral *L = dyn_cast<IntegerLiteral>(Exp)) {
|
||||
|
@ -9957,7 +9962,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
|
|||
// performance problems. Only do so in C++11 for now.
|
||||
if (Exp->isRValue() && (Exp->getType()->isArrayType() ||
|
||||
Exp->getType()->isRecordType()) &&
|
||||
!Ctx.getLangOpts().CPlusPlus11) {
|
||||
!Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) {
|
||||
IsConst = false;
|
||||
return true;
|
||||
}
|
||||
|
@ -9972,7 +9977,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
|
|||
/// will be applied to the result.
|
||||
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
|
||||
bool IsConst;
|
||||
if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
|
||||
if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false))
|
||||
return IsConst;
|
||||
|
||||
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
|
||||
|
@ -10097,7 +10102,7 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
|
|||
void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
|
||||
bool IsConst;
|
||||
EvalResult EvalResult;
|
||||
if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
|
||||
if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) {
|
||||
EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
|
||||
(void)::EvaluateAsRValue(Info, this, EvalResult.Val);
|
||||
}
|
||||
|
|
|
@ -9935,28 +9935,6 @@ void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) {
|
|||
::CheckBoolLikeConversion(*this, E, CC);
|
||||
}
|
||||
|
||||
/// Diagnose when expression is an integer constant expression and its evaluation
|
||||
/// results in integer overflow
|
||||
void Sema::CheckForIntOverflow (Expr *E) {
|
||||
// Use a work list to deal with nested struct initializers.
|
||||
SmallVector<Expr *, 2> Exprs(1, E);
|
||||
|
||||
do {
|
||||
Expr *E = Exprs.pop_back_val();
|
||||
|
||||
if (isa<BinaryOperator>(E->IgnoreParenCasts())) {
|
||||
E->IgnoreParenCasts()->EvaluateForOverflow(Context);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto InitList = dyn_cast<InitListExpr>(E))
|
||||
Exprs.append(InitList->inits().begin(), InitList->inits().end());
|
||||
|
||||
if (isa<ObjCBoxedExpr>(E))
|
||||
E->IgnoreParenCasts()->EvaluateForOverflow(Context);
|
||||
} while (!Exprs.empty());
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// \brief Visitor for expressions which looks for unsequenced operations on the
|
||||
/// same object.
|
||||
|
@ -10458,7 +10436,7 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc,
|
|||
if (!E->isInstantiationDependent())
|
||||
CheckUnsequencedOperations(E);
|
||||
if (!IsConstexpr && !E->isValueDependent())
|
||||
CheckForIntOverflow(E);
|
||||
E->EvaluateForOverflow(Context);
|
||||
DiagnoseMisalignedMembers();
|
||||
}
|
||||
|
||||
|
|
|
@ -134,9 +134,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -134,9 +134,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp for simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp target parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp target simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -110,9 +110,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target teams distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
|
|
|
@ -110,9 +110,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target teams distribute simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
|
|
|
@ -107,9 +107,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
#pragma omp taskloop simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
|
|
|
@ -123,9 +123,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -123,9 +123,8 @@ S3 h; // expected-note 2 {{'h' defined here}}
|
|||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int i; // expected-note {{'i' defined here}}
|
||||
// expected-note@+1 {{declared here}}
|
||||
int &j = i;
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -152,7 +152,13 @@ uint64_t check_integer_overflows(int i) {
|
|||
uint64_t b2 = b[4608 * 1024 * 1024] + 1;
|
||||
|
||||
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
|
||||
(void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);
|
||||
int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
|
||||
|
||||
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
|
||||
int j2 = -(4608 * 1024 * 1024);
|
||||
|
||||
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
|
||||
uint64_t j3 = b[4608 * 1024 * 1024];
|
||||
|
||||
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
|
||||
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
|
||||
|
|
Loading…
Reference in New Issue