summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-19 05:36:41 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-19 05:36:41 +0000
commitb2f4cdb233b4d895e862835279faae1adf6047dd (patch)
treebe88235e94c81f5ca7258b4ec57c142603201528 /clang/lib/CodeGen/CodeGenModule.cpp
parent3c50fdf4cad0c5842aafd5ea1237e83664730fc3 (diff)
downloadbcm5719-llvm-b2f4cdb233b4d895e862835279faae1adf6047dd.tar.gz
bcm5719-llvm-b2f4cdb233b4d895e862835279faae1adf6047dd.zip
Emission of global variable initialializer was broken in rare
situation where a tentative decl was emitted *after* the actual initialization. This occurs in some rare situations with static decls. - PR3613. - I'm not particularly happy with this fix, but I don't see a simpler or more elegant solution yet. llvm-svn: 65018
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ca6ba14f855..17662ef340e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -444,7 +444,7 @@ void CodeGenModule::EmitDeferred() {
// FIXME: This is missing some important cases. For example, we
// need to check for uses in an alias.
if (!GlobalDeclMap.count(getMangledName(D))) {
- i++;
+ ++i;
continue;
}
@@ -623,6 +623,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
Init = llvm::Constant::getNullValue(InitTy);
} else {
Init = EmitConstantExpr(D->getInit());
+ if (!Init)
+ ErrorUnsupported(D, "static initializer");
}
const llvm::Type* InitType = Init->getType();
@@ -634,6 +636,26 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::GlobalValue::ExternalLinkage,
0, getMangledName(D),
&getModule(), 0, ASTTy.getAddressSpace());
+
+ } else if (GV->hasInitializer() && !GV->getInitializer()->isNullValue()) {
+ // If we already have this global and it has an initializer, then
+ // we are in the rare situation where we emitted the defining
+ // declaration of the global and are now being asked to emit a
+ // definition which would be common. This occurs, for example, in
+ // the following situation because statics can be emitted out of
+ // order:
+ //
+ // static int x;
+ // static int *y = &x;
+ // static int x = 10;
+ // int **z = &y;
+ //
+ // Bail here so we don't blow away the definition. Note that if we
+ // can't distinguish here if we emitted a definition with a null
+ // initializer, but this case is safe.
+ assert(!D->getInit() && "Emitting multiple definitions of a decl!");
+ return;
+
} else if (GV->getType() !=
llvm::PointerType::get(InitType, ASTTy.getAddressSpace())) {
// We have a definition after a prototype with the wrong type.
OpenPOWER on IntegriCloud