diff options
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 24 | ||||
| -rw-r--r-- | clang/test/CodeGen/tentative-array.c | 4 | 
2 files changed, 26 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c93b12fc790..633aa209d49 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<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 @@ 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<AlignedAttr>()) {      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 00000000000..71231237faf --- /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;  | 

