]> granicus.if.org Git - clang/commitdiff
CodeGen: Compound literals with funny types shouldn't crash
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 14 Dec 2014 12:16:43 +0000 (12:16 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 14 Dec 2014 12:16:43 +0000 (12:16 +0000)
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

lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
test/CodeGenCXX/compound-literals.cpp
test/CodeGenCXX/lambda-expressions.cpp

index ddfea03bebe6893e889f98782bf4cf6d08680f02..ac58d624e6f986d2359402dc4c0113cb345646d0 100644 (file)
@@ -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)
index a9e63dc7f76afab43931d00eda1849734f19cb20..7e3c5b5a326131d49ad27560c5555ba71b857a88 100644 (file)
@@ -1411,8 +1411,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
     // anything here.
     if (!E->getType()->isVariableArrayType()) {
       assert(isa<llvm::PointerType>(V->getType()) && "Expected pointer");
-      assert(isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
-                                 ->getElementType()) &&
+      V = CGF.Builder.CreatePointerCast(
+          V, ConvertType(E->getType())->getPointerTo());
+
+      assert(isa<llvm::ArrayType>(V->getType()->getPointerElementType()) &&
              "Expected pointer to array");
       V = Builder.CreateStructGEP(V, 0, "arraydecay");
     }
index f1d88027c4fa7f052bb0bf7f8ca1fc689242fa86..e7710939bd2deb4c0e6bee00f70326238f831a9a 100644 (file)
@@ -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
index 2f9a4f2d4f55657aa6a3bc1c93990053d28cde89..e35c6163d564a2235b34b1a201d719755728101a 100644 (file)
@@ -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[] = {};