Author: ahatanak Date: Tue Oct 18 14:05:41 2016 New Revision: 284516 URL: http://llvm.org/viewvc/llvm-project?rev=284516&view=rev Log: [CodeGen][ObjC] Do not call objc_storeStrong when initializing a constexpr variable.
When compiling a constexpr NSString initialized with an objective-c string literal, CodeGen emits objc_storeStrong on an uninitialized alloca, which causes a crash. This patch folds the code in EmitScalarInit into EmitStoreThroughLValue and fixes the crash by calling objc_retain on the string instead of using objc_storeStrong. rdar://problem/28562009 Differential Revision: https://reviews.llvm.org/D25547 Added: cfe/trunk/test/CodeGenObjCXX/arc-constexpr.mm Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGObjC.cpp cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=284516&r1=284515&r2=284516&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Oct 18 14:05:41 2016 @@ -774,37 +774,6 @@ void CodeGenFunction::EmitScalarInit(con EmitStoreOfScalar(value, lvalue, /* isInitialization */ true); } -/// EmitScalarInit - Initialize the given lvalue with the given object. -void CodeGenFunction::EmitScalarInit(llvm::Value *init, LValue lvalue) { - Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime(); - if (!lifetime) - return EmitStoreThroughLValue(RValue::get(init), lvalue, true); - - switch (lifetime) { - case Qualifiers::OCL_None: - llvm_unreachable("present but none"); - - case Qualifiers::OCL_ExplicitNone: - // nothing to do - break; - - case Qualifiers::OCL_Strong: - init = EmitARCRetain(lvalue.getType(), init); - break; - - case Qualifiers::OCL_Weak: - // Initialize and then skip the primitive store. - EmitARCInitWeak(lvalue.getAddress(), init); - return; - - case Qualifiers::OCL_Autoreleasing: - init = EmitARCRetainAutorelease(lvalue.getType(), init); - break; - } - - EmitStoreOfScalar(init, lvalue, /* isInitialization */ true); -} - /// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the /// non-zero parts of the specified initializer with equal or fewer than /// NumStores scalar stores. Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=284516&r1=284515&r2=284516&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Oct 18 14:05:41 2016 @@ -1629,11 +1629,19 @@ void CodeGenFunction::EmitStoreThroughLV break; case Qualifiers::OCL_Strong: + if (isInit) { + Src = RValue::get(EmitARCRetain(Dst.getType(), Src.getScalarVal())); + break; + } EmitARCStoreStrong(Dst, Src.getScalarVal(), /*ignore*/ true); return; case Qualifiers::OCL_Weak: - EmitARCStoreWeak(Dst.getAddress(), Src.getScalarVal(), /*ignore*/ true); + if (isInit) + // Initialize and then skip the primitive store. + EmitARCInitWeak(Dst.getAddress(), Src.getScalarVal()); + else + EmitARCStoreWeak(Dst.getAddress(), Src.getScalarVal(), /*ignore*/ true); return; case Qualifiers::OCL_Autoreleasing: Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=284516&r1=284515&r2=284516&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Oct 18 14:05:41 2016 @@ -1662,7 +1662,8 @@ void CodeGenFunction::EmitObjCForCollect elementLValue = EmitLValue(cast<Expr>(S.getElement())); EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue); } else { - EmitScalarInit(CurrentItem, elementLValue); + EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue, + /*isInit*/ true); } // If we do have an element variable, this assignment is the end of Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=284516&r1=284515&r2=284516&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Oct 18 14:05:41 2016 @@ -188,7 +188,7 @@ static Address castValueFromUintptr(Code auto *RefVal = TmpAddr.getPointer(); TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name) + ".ref"); auto TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType); - CGF.EmitScalarInit(RefVal, TmpLVal); + CGF.EmitStoreThroughLValue(RValue::get(RefVal), TmpLVal, /*isInit*/ true); } return TmpAddr; @@ -2192,7 +2192,7 @@ static LValue createSectionLVal(CodeGenF llvm::Value *Init = nullptr) { auto LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty); if (Init) - CGF.EmitScalarInit(Init, LVal); + CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true); return LVal; } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=284516&r1=284515&r2=284516&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Oct 18 14:05:41 2016 @@ -2119,7 +2119,6 @@ public: void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit); - void EmitScalarInit(llvm::Value *init, LValue lvalue); typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, llvm::Value *Address); Added: cfe/trunk/test/CodeGenObjCXX/arc-constexpr.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-constexpr.mm?rev=284516&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/arc-constexpr.mm (added) +++ cfe/trunk/test/CodeGenObjCXX/arc-constexpr.mm Tue Oct 18 14:05:41 2016 @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -o - -std=c++11 %s | FileCheck %s + +// CHECK: %[[TYPE:[a-z0-9]+]] = type opaque +// CHECK: @[[CFSTRING:[a-z0-9_]+]] = private global %struct.__NSConstantString_tag + +// CHECK: define void @_Z5test1v +// CHECK: %[[ALLOCA:[A-Z]+]] = alloca %[[TYPE]]* +// CHECK: %[[V0:[0-9]+]] = call i8* @objc_retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] +// CHECK: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to %[[TYPE]]* +// CHECK: store %[[TYPE]]* %[[V1]], %[[TYPE]]** %[[ALLOCA]] +// CHECK: %[[V2:[0-9]+]] = bitcast %[[TYPE]]** %[[ALLOCA]] +// CHECK: call void @objc_storeStrong(i8** %[[V2]], i8* null) + +@class NSString; + +void test1() { + constexpr NSString *S = @"abc"; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits