diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-27 23:18:37 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-27 23:18:37 +0000 |
commit | c1b66e6003262b284937b542aa159a0c79619ff4 (patch) | |
tree | acd568ae3abbde66d3406bd4e45bfe966f09ebc9 /lib | |
parent | 3306ec1923973d7b5767b23ba95915af2fec87d7 (diff) | |
download | clang-c1b66e6003262b284937b542aa159a0c79619ff4.tar.gz clang-c1b66e6003262b284937b542aa159a0c79619ff4.tar.bz2 clang-c1b66e6003262b284937b542aa159a0c79619ff4.tar.xz |
When evaluating integer expressions include a check for sub-expressions
depth and error if we exceed a max value, to make sure we avoid a stack overflow.
This is a hacky temporary fix. rdar://10913206.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 44e41864f0..31750ead25 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -44,6 +44,7 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SaveAndRestore.h" #include <cstring> #include <functional> @@ -445,13 +446,18 @@ namespace { /// are suppressed. bool CheckingPotentialConstantExpression; + /// \brief Stack depth of IntExprEvaluator. + /// We check this against a maximum value to avoid stack overflow, see + /// test case in test/Sema/many-logical-ops.c. + // FIXME: This is a hack; handle properly unlimited logical ops. + unsigned IntExprEvaluatorDepth; EvalInfo(const ASTContext &C, Expr::EvalStatus &S) : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0), CallStackDepth(0), NextCallIndex(1), BottomFrame(*this, SourceLocation(), 0, 0, 0), EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false), - CheckingPotentialConstantExpression(false) {} + CheckingPotentialConstantExpression(false), IntExprEvaluatorDepth(0) {} const CCValue *getOpaqueValue(const OpaqueValueExpr *e) const { MapTy::const_iterator i = OpaqueValues.find(e); @@ -4067,6 +4073,20 @@ public: bool ZeroInitialization(const Expr *E) { return Success(0, E); } + // FIXME: See EvalInfo::IntExprEvaluatorDepth. + bool Visit(const Expr *E) { + SaveAndRestore<unsigned> Depth(Info.IntExprEvaluatorDepth, + Info.IntExprEvaluatorDepth+1); + const unsigned MaxDepth = 512; + if (Depth.get() > MaxDepth) { + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::err_intexpr_depth_limit_exceeded); + return false; + } + + return ExprEvaluatorBaseTy::Visit(E); + } + //===--------------------------------------------------------------------===// // Visitor Methods //===--------------------------------------------------------------------===// |