diff options
| author | Nick Lewycky <nicholas@mxc.ca> | 2017-04-29 00:07:27 +0000 |
|---|---|---|
| committer | Nick Lewycky <nicholas@mxc.ca> | 2017-04-29 00:07:27 +0000 |
| commit | 19ae6dc853d3d4f867a6d1308f3c3fcca754a7a2 (patch) | |
| tree | ee057e33fb728e9315b7be34f7730dc87e866d3b /clang | |
| parent | 4346ae1a058c257bbd09e335e3a318d9e99fd2f1 (diff) | |
| download | bcm5719-llvm-19ae6dc853d3d4f867a6d1308f3c3fcca754a7a2.tar.gz bcm5719-llvm-19ae6dc853d3d4f867a6d1308f3c3fcca754a7a2.zip | |
ObjCBoxedExpr can't be evaluated by the constant expression evaluator.
A boxed expression evaluates its subexpr and then calls an objc method to transform it into another value with pointer type. The objc method can never be constexpr and therefore this expression can never be evaluated. Fixes a miscompile boxing expressions with side-effects.
Also make ObjCBoxedExpr handling a normal part of the expression evaluator instead of being the only case besides full-expression where we check for integer overflow.
llvm-svn: 301721
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 1 | ||||
| -rw-r--r-- | clang/test/CodeGenObjCXX/boxing.mm | 12 |
4 files changed, 20 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 2947b97bfcd..dcbbe8a944b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5481,8 +5481,11 @@ public: bool VisitUnaryAddrOf(const UnaryOperator *E); bool VisitObjCStringLiteral(const ObjCStringLiteral *E) { return Success(E); } - bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E) - { return Success(E); } + bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E) { + if (Info.noteFailure()) + EvaluateIgnoredValue(Info, E->getSubExpr()); + return Error(E); + } bool VisitAddrLabelExpr(const AddrLabelExpr *E) { return Success(E); } bool VisitCallExpr(const CallExpr *E); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 044ec74679d..ea6f16e1c87 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9882,6 +9882,9 @@ void Sema::CheckForIntOverflow (Expr *E) { 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()); } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 9cc443ed4fd..a44e9243e3c 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -595,7 +595,6 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { break; } } - CheckForIntOverflow(ValueExpr); // FIXME: Do I need to do anything special with BoolTy expressions? // Look for the appropriate method within NSNumber. diff --git a/clang/test/CodeGenObjCXX/boxing.mm b/clang/test/CodeGenObjCXX/boxing.mm new file mode 100644 index 00000000000..dc353603581 --- /dev/null +++ b/clang/test/CodeGenObjCXX/boxing.mm @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +@interface NSNumber ++ (id)numberWithInt:(int)n; +@end + +int n = 1; +int m = (@(n++), 0); + +// CHECK: define {{.*}} @__cxx_global_var_init() +// CHECK: load i32, i32* @n +// CHECK: store i32 %{{.*}}, i32* @n |

