]> granicus.if.org Git - clang/commitdiff
ObjCBoxedExpr can't be evaluated by the constant expression evaluator.
authorNick Lewycky <nicholas@mxc.ca>
Sat, 29 Apr 2017 00:07:27 +0000 (00:07 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sat, 29 Apr 2017 00:07:27 +0000 (00:07 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@301721 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaExprObjC.cpp
test/CodeGenObjCXX/boxing.mm [new file with mode: 0644]

index 2947b97bfcde4b75b744951c66f39bef4412094d..dcbbe8a944b41ff24f7c60f28af30605cdd20520 100644 (file)
@@ -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);
index 044ec74679d5c059c85b6afb2fd72f833d5677c2..ea6f16e1c87f6ef95498101f31c2c8888b03432b 100644 (file)
@@ -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());
 }
 
index 9cc443ed4fd985aa2a0ecfde9a341123deeffbe2..a44e9243e3c52ca5a06230a04f366a880a91da94 100644 (file)
@@ -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/test/CodeGenObjCXX/boxing.mm b/test/CodeGenObjCXX/boxing.mm
new file mode 100644 (file)
index 0000000..dc35360
--- /dev/null
@@ -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