From 19ae6dc853d3d4f867a6d1308f3c3fcca754a7a2 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sat, 29 Apr 2017 00:07:27 +0000 Subject: [PATCH] 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 --- clang/lib/AST/ExprConstant.cpp | 7 +++++-- clang/lib/Sema/SemaChecking.cpp | 3 +++ clang/lib/Sema/SemaExprObjC.cpp | 1 - clang/test/CodeGenObjCXX/boxing.mm | 12 ++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGenObjCXX/boxing.mm diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 2947b97..dcbbe8a 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 044ec74..ea6f16e 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(E)) Exprs.append(InitList->inits().begin(), InitList->inits().end()); + + if (isa(E)) + E->IgnoreParenCasts()->EvaluateForOverflow(Context); } while (!Exprs.empty()); } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 9cc443e..a44e924 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 0000000..dc35360 --- /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 -- 2.7.4