diff options
author | David Bolvansky <david.bolvansky@gmail.com> | 2018-10-18 20:49:06 +0000 |
---|---|---|
committer | David Bolvansky <david.bolvansky@gmail.com> | 2018-10-18 20:49:06 +0000 |
commit | 3b6ae57654a5cedcf06ae8fd43f704fa5940342a (patch) | |
tree | 37dab75d77e4a89cfac5531fe264891fe124aa3e | |
parent | 1b051b2910cbe9cbf477bf65de1670c07b3c6d11 (diff) | |
download | bcm5719-llvm-3b6ae57654a5cedcf06ae8fd43f704fa5940342a.tar.gz bcm5719-llvm-3b6ae57654a5cedcf06ae8fd43f704fa5940342a.zip |
[Diagnostics] Check for integer overflow in array size expressions
Summary: Fixes PR27439
Reviewers: rsmith, Rakete1111
Reviewed By: rsmith
Subscribers: Rakete1111, cfe-commits
Differential Revision: https://reviews.llvm.org/D52750
llvm-svn: 344759
-rw-r--r-- | clang/include/clang/AST/Expr.h | 9 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/test/Sema/integer-overflow.c | 3 |
4 files changed, 24 insertions, 3 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 8bc14e12df3..8817aa4d6af 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -631,8 +631,13 @@ public: /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded /// integer. This must be called on an expression that constant folds to an /// integer. - llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, - SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const; + llvm::APSInt EvaluateKnownConstInt( + const ASTContext &Ctx, + SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const; + + llvm::APSInt EvaluateKnownConstIntCheckOverflow( + const ASTContext &Ctx, + SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const; void EvaluateForOverflow(const ASTContext &Ctx) const; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index de0de5d13cd..c4d1245071d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10851,6 +10851,19 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx, return EvalResult.Val.getInt(); } +APSInt Expr::EvaluateKnownConstIntCheckOverflow( + const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const { + EvalResult EvalResult; + EvalResult.Diag = Diag; + EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); + bool Result = ::EvaluateAsRValue(Info, this, EvalResult.Val); + (void)Result; + assert(Result && "Could not evaluate expression"); + assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); + + return EvalResult.Val.getInt(); +} + void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { bool IsConst; EvalResult EvalResult; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 72499b0e905..597f220bc4c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14105,7 +14105,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) - *Result = E->EvaluateKnownConstInt(Context); + *Result = E->EvaluateKnownConstIntCheckOverflow(Context); return E; } diff --git a/clang/test/Sema/integer-overflow.c b/clang/test/Sema/integer-overflow.c index d66ce7ff164..39395d9bc1f 100644 --- a/clang/test/Sema/integer-overflow.c +++ b/clang/test/Sema/integer-overflow.c @@ -172,6 +172,9 @@ void check_integer_overflows_in_function_calls() { // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} (void)f2(0, f0(4608 * 1024 * 1024)); } +void check_integer_overflows_in_array_size() { + int arr[4608 * 1024 * 1024]; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}} +} struct s { unsigned x; |