aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-01-04 02:08:04 +0000
committerAnders Carlsson <andersca@mac.com>2009-01-04 02:08:04 +0000
commitb723f7520bcce5f13ccaae557c16a1e7133b6908 (patch)
tree3797c27d14a598c9631f226d0c0dde78b9038db2
parent5c5a7ee24270eb670881068d4baa2e2991f23214 (diff)
Fix the bug that would cause Python to crash at startup.
When emitting the static variables we need to make sure that the order is preserved. Fix this by making StaticDecls a std::list which has O(1) random removal. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61621 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenModule.cpp21
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--test/CodeGen/static-order.c19
3 files changed, 33 insertions, 11 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index fc1b108b0d..021e9af676 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -361,26 +361,27 @@ void CodeGenModule::EmitStatics() {
bool Changed;
do {
Changed = false;
- for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
- const ValueDecl *D = StaticDecls[i];
-
+
+ for (std::list<const ValueDecl*>::iterator i = StaticDecls.begin(),
+ e = StaticDecls.end(); i != e; ) {
+ const ValueDecl *D = *i;
+
// Check if we have used a decl with the same name
// FIXME: The AST should have some sort of aggregate decls or
// global symbol map.
// FIXME: This is missing some important cases. For example, we
// need to check for uses in an alias and in a constructor.
- if (!GlobalDeclMap.count(D->getIdentifier()))
+ if (!GlobalDeclMap.count(D->getIdentifier())) {
+ i++;
continue;
-
+ }
+
// Emit the definition.
EmitGlobalDefinition(D);
// Erase the used decl from the list.
- StaticDecls[i] = StaticDecls.back();
- StaticDecls.pop_back();
- --i;
- --e;
-
+ i = StaticDecls.erase(i);
+
// Remember that we made a change.
Changed = true;
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 3f604dd048..0bd0e2c724 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -21,6 +21,8 @@
#include "CGCall.h"
+#include <list>
+
namespace llvm {
class Module;
class Constant;
@@ -97,7 +99,7 @@ class CodeGenModule {
/// will lazily emit definitions for only the decls that were
/// actually used. This should contain only Function and Var decls,
/// and only those which actually define something.
- std::vector<const ValueDecl*> StaticDecls;
+ std::list<const ValueDecl*> StaticDecls;
/// GlobalCtors - Store the list of global constructors and their
/// respective priorities to be emitted when the translation unit is
diff --git a/test/CodeGen/static-order.c b/test/CodeGen/static-order.c
new file mode 100644
index 0000000000..c63f4ed892
--- /dev/null
+++ b/test/CodeGen/static-order.c
@@ -0,0 +1,19 @@
+// RUN: clang -emit-llvm -o - %s | not grep "zeroinitializer"
+
+struct s {
+ int a;
+};
+
+static void *v;
+
+static struct s a;
+
+static struct s a = {
+ 10
+};
+
+void *f()
+{
+ if (a.a)
+ return v;
+}