From: David Majnemer Date: Sun, 14 Dec 2014 12:16:43 +0000 (+0000) Subject: CodeGen: Compound literals with funny types shouldn't crash X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=320a846584599c9cfb339b6bb0a7a9634a397414;p=clang CodeGen: Compound literals with funny types shouldn't crash CodeGen assumed that a compound literal with array type should have a corresponding LLVM IR array type. We had two bugs in this area: - Zero sized arrays in compound literals would lead to the creation of an opaque type. This is unnecessary, we should just create an array type with a bound of zero. - Funny record types (like unions) lead to exotic IR types for compound literals. In this case, CodeGen must be prepared to deal with the possibility that it might not have an array IR type. This fixes PR21912. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224219 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index ddfea03beb..ac58d624e6 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -1217,7 +1217,8 @@ llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value, CAT->getElementType(), CGF); // Emit initializer elements. - llvm::Type *CommonElementType = nullptr; + llvm::Type *CommonElementType = + getTypes().ConvertType(CAT->getElementType()); for (unsigned I = 0; I < NumElements; ++I) { llvm::Constant *C = Filler; if (I < NumInitElts) diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index a9e63dc7f7..7e3c5b5a32 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1411,8 +1411,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // anything here. if (!E->getType()->isVariableArrayType()) { assert(isa(V->getType()) && "Expected pointer"); - assert(isa(cast(V->getType()) - ->getElementType()) && + V = CGF.Builder.CreatePointerCast( + V, ConvertType(E->getType())->getPointerTo()); + + assert(isa(V->getType()->getPointerElementType()) && "Expected pointer to array"); V = Builder.CreateStructGEP(V, 0, "arraydecay"); } diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index f1d88027c4..e7710939bd 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s struct X { X(); @@ -42,3 +42,16 @@ struct Z { int i[3]; }; int *p = (Z){ {1, 2, 3} }.i; // CHECK: define {{.*}}__cxx_global_var_init() // CHECK: store i32* getelementptr inbounds (%struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p + + +int *PR21912_1 = (int []){}; +// CHECK-LABEL: define {{.*}}__cxx_global_var_init1() +// CHECK: store i32* getelementptr inbounds ([0 x i32]* @.compoundliteral2, i32 0, i32 0), i32** @PR21912_1 + +union PR21912Ty { + long long l; + double d; +}; +union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}}; +// CHECK-LABEL: define {{.*}}__cxx_global_var_init3() +// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2 diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp index 2f9a4f2d4f..e35c6163d5 100644 --- a/test/CodeGenCXX/lambda-expressions.cpp +++ b/test/CodeGenCXX/lambda-expressions.cpp @@ -81,7 +81,7 @@ int g() { }; // PR14773 -// CHECK: [[ARRVAL:%[0-9a-zA-Z]*]] = load i32* getelementptr inbounds ([0 x i32]* bitcast (<{}>* @_ZZ14staticarrayrefvE5array to [0 x i32]*), i32 0, i64 0), align 4 +// CHECK: [[ARRVAL:%[0-9a-zA-Z]*]] = load i32* getelementptr inbounds ([0 x i32]* @_ZZ14staticarrayrefvE5array, i32 0, i64 0), align 4 // CHECK-NEXT: store i32 [[ARRVAL]] void staticarrayref(){ static int array[] = {};