[cfe-commits] r65018 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp test/CodeGen/PR3613-static-decl.c
Daniel Dunbar
daniel at zuster.org
Wed Feb 18 21:36:42 PST 2009
Author: ddunbar
Date: Wed Feb 18 23:36:41 2009
New Revision: 65018
URL: http://llvm.org/viewvc/llvm-project?rev=65018&view=rev
Log:
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.
Added:
cfe/trunk/test/CodeGen/PR3613-static-decl.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=65018&r1=65017&r2=65018&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Feb 18 23:36:41 2009
@@ -444,7 +444,7 @@
// 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 @@
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 @@
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.
Added: cfe/trunk/test/CodeGen/PR3613-static-decl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/PR3613-static-decl.c?rev=65018&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/PR3613-static-decl.c (added)
+++ cfe/trunk/test/CodeGen/PR3613-static-decl.c Wed Feb 18 23:36:41 2009
@@ -0,0 +1,16 @@
+// RUN: clang -triple i386-unknown-unknown -emit-llvm -o %t %s &&
+// RUN: grep '@g0 = internal global .struct.s0 <{ i32 3 }>' %t | count 1
+
+struct s0 {
+ int a;
+};
+
+static struct s0 g0;
+
+static int f0(void) {
+ return g0.a;
+}
+
+static struct s0 g0 = {3};
+
+void *g1 = f0;
More information about the cfe-commits
mailing list