diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 15 |
4 files changed, 29 insertions, 12 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 0d8f764df5..9af16f3201 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -5183,6 +5183,18 @@ void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) { AnalyzeImplicitConversions(*this, E, CC); } +/// Diagnose when expression is an integer constant expression and its evaluation +/// results in integer overflow +void Sema::CheckForIntOverflow (Expr *E) { + if (const BinaryOperator *BExpr = dyn_cast<BinaryOperator>(E->IgnoreParens())) { + unsigned Opc = BExpr->getOpcode(); + if (Opc != BO_Add && Opc != BO_Sub && Opc != BO_Mul) + return; + llvm::SmallVector<PartialDiagnosticAt, 4> Diags; + E->EvaluateForOverflow(Context, &Diags); + } +} + namespace { /// \brief Visitor for expressions which looks for unsequenced operations on the /// same object. @@ -5622,9 +5634,12 @@ void Sema::CheckUnsequencedOperations(Expr *E) { } } -void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc) { +void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, + bool IsConstexpr) { CheckImplicitConversions(E, CheckLoc); CheckUnsequencedOperations(E); + if (!IsConstexpr && !E->isValueDependent()) + CheckForIntOverflow(E); } void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ca9610b7d7..538434db00 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7045,7 +7045,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // struct T { S a, b; } t = { Temp(), Temp() } // // we should destroy the first Temp before constructing the second. - ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation()); + ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), + false, + VDecl->isConstexpr()); if (Result.isInvalid()) { VDecl->setInvalidDecl(); return; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2658a3a2ce..c70041ba51 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -5469,7 +5469,8 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { } ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, - bool DiscardedValue) { + bool DiscardedValue, + bool IsConstexpr) { ExprResult FullExpr = Owned(FE); if (!FullExpr.get()) @@ -5497,7 +5498,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, return ExprError(); } - CheckCompletedExpr(FullExpr.get(), CC); + CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr); return MaybeCreateExprWithCleanups(FullExpr); } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index a2daa18d45..fd3ee0d9f5 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -338,6 +338,12 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal, // Recover from an error by just forgetting about it. } } + + LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false, + getLangOpts().CPlusPlus11).take(); + if (RHSVal) + RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false, + getLangOpts().CPlusPlus11).take(); CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc, ColonLoc); @@ -732,14 +738,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, } else { // We already verified that the expression has a i-c-e value (C99 // 6.8.4.2p3) - get that value now. - SmallVector<PartialDiagnosticAt, 8> Diags; - LoVal = Lo->EvaluateKnownConstInt(Context, &Diags); - if (Diags.size() == 1 && - Diags[0].second.getDiagID() == diag::note_constexpr_overflow) { - Diag(Lo->getLocStart(), diag::warn_case_constant_overflow) << - LoVal.toString(10); - Diag(Diags[0].first, Diags[0].second); - } + LoVal = Lo->EvaluateKnownConstInt(Context); // If the LHS is not the same type as the condition, insert an implicit // cast. |