[cfe-commits] r51787 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp test/CodeGen/tentative-array.c

Eli Friedman eli.friedman at gmail.com
Fri May 30 13:39:55 PDT 2008


Author: efriedma
Date: Fri May 30 15:39:54 2008
New Revision: 51787

URL: http://llvm.org/viewvc/llvm-project?rev=51787&view=rev
Log:
PR1893: Fix up the type of tentative definitions of incomplete array 
types so that they end up the correct size.


Added:
    cfe/trunk/test/CodeGen/tentative-array.c
Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=51787&r1=51786&r2=51787&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri May 30 15:39:54 2008
@@ -411,7 +411,18 @@
       llvm::PointerType::get(VarTy, ASTTy.getAddressSpace());
 
   if (D->getInit() == 0) {
-    Init = llvm::Constant::getNullValue(VarTy);
+    // This is a tentative definition; tentative definitions are
+    // implicitly initialized with { 0 }
+    const llvm::Type* InitTy;
+    if (ASTTy->isIncompleteArrayType()) {
+      // An incomplete array is normally [ TYPE x 0 ], but we need
+      // to fix it to [ TYPE x 1 ].
+      const llvm::ArrayType* ATy = cast<llvm::ArrayType>(VarTy);
+      InitTy = llvm::ArrayType::get(ATy->getElementType(), 1);
+    } else {
+      InitTy = VarTy;
+    }
+    Init = llvm::Constant::getNullValue(InitTy);
   } else {
     Init = EmitGlobalInit(D->getInit());
   }
@@ -435,6 +446,10 @@
     // and then a definition of a different type (e.g. "int x[10];"). This also
     // happens when an initializer has a different type from the type of the
     // global (this happens with unions).
+    //
+    // FIXME: This also ends up happening if there's a definition followed by
+    // a tentative definition!  (Although Sema rejects that construct
+    // at the moment.)
 
     // Save the old global
     llvm::GlobalVariable *OldGV = GV;
@@ -470,7 +485,12 @@
 
   GV->setInitializer(Init);
 
-  unsigned Align = Context.getTypeAlign(D->getType());
+  // FIXME: This is silly; getTypeAlign should just work for incomplete arrays
+  unsigned Align;
+  if (const IncompleteArrayType* IAT = D->getType()->getAsIncompleteArrayType())
+    Align = Context.getTypeAlign(IAT->getElementType());
+  else
+    Align = Context.getTypeAlign(D->getType());
   if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) {
     Align = std::max(Align, AA->getAlignment());
   }

Added: cfe/trunk/test/CodeGen/tentative-array.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/tentative-array.c?rev=51787&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/tentative-array.c (added)
+++ cfe/trunk/test/CodeGen/tentative-array.c Fri May 30 15:39:54 2008
@@ -0,0 +1,4 @@
+// RUN: clang -emit-llvm < %s -triple=i686-apple-darwin9 | grep "global \[1 x i32\]"
+
+int r[];
+int (*a)[] = &r;





More information about the cfe-commits mailing list