diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c93b12fc7902..633aa209d499 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -411,7 +411,18 @@ void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { 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(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 @@ void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { // 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 @@ void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { 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()) { Align = std::max(Align, AA->getAlignment()); } diff --git a/clang/test/CodeGen/tentative-array.c b/clang/test/CodeGen/tentative-array.c new file mode 100644 index 000000000000..71231237fafe --- /dev/null +++ b/clang/test/CodeGen/tentative-array.c @@ -0,0 +1,4 @@ +// RUN: clang -emit-llvm < %s -triple=i686-apple-darwin9 | grep "global \[1 x i32\]" + +int r[]; +int (*a)[] = &r;