]> granicus.if.org Git - clang/commitdiff
Fix the bug that would cause Python to crash at startup.
authorAnders Carlsson <andersca@mac.com>
Sun, 4 Jan 2009 02:08:04 +0000 (02:08 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 4 Jan 2009 02:08:04 +0000 (02:08 +0000)
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

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGen/static-order.c [new file with mode: 0644]

index fc1b108b0d6e722bb5abfe4801f819d2c397276e..021e9af6765207b5ca1cd516a995208006aec286 100644 (file)
@@ -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;
     }
index 3f604dd048b25ea7bb25cb6aa39f027e80e9942a..0bd0e2c724fd7406a1be3c5ecd0e401316d53cee 100644 (file)
@@ -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 (file)
index 0000000..c63f4ed
--- /dev/null
@@ -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;
+}