summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2017-04-29 00:07:27 +0000
committerNick Lewycky <nicholas@mxc.ca>2017-04-29 00:07:27 +0000
commit19ae6dc853d3d4f867a6d1308f3c3fcca754a7a2 (patch)
treeee057e33fb728e9315b7be34f7730dc87e866d3b /clang
parent4346ae1a058c257bbd09e335e3a318d9e99fd2f1 (diff)
downloadbcm5719-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.cpp7
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp1
-rw-r--r--clang/test/CodeGenObjCXX/boxing.mm12
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
OpenPOWER on IntegriCloud