[llvm-commits] [dragonegg] r156267 - in /dragonegg/trunk: src/Backend.cpp test/validator/c/2012-05-06-SelfInit.c

Duncan Sands baldrick at free.fr
Sun May 6 12:35:11 PDT 2012


Author: baldrick
Date: Sun May  6 14:35:11 2012
New Revision: 156267

URL: http://llvm.org/viewvc/llvm-project?rev=156267&view=rev
Log:
It is theoretically possible for a global variable to be initialized to itself
without the element type being a pointer type (but I wasn't able to synthesize
a testcase).  If this ever does happen, ensure it is harmless.  Add a testcase
checking that we get a nice type for the global in the standard self-init case
(rather than getting an extra *, i8** rather than i8*, which the generic code
would give in this case).

Added:
    dragonegg/trunk/test/validator/c/2012-05-06-SelfInit.c
Modified:
    dragonegg/trunk/src/Backend.cpp

Modified: dragonegg/trunk/src/Backend.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Backend.cpp?rev=156267&r1=156266&r2=156267&view=diff
==============================================================================
--- dragonegg/trunk/src/Backend.cpp (original)
+++ dragonegg/trunk/src/Backend.cpp Sun May  6 14:35:11 2012
@@ -985,30 +985,30 @@
     Init = ConvertInitializer(DECL_INITIAL(decl));
   }
 
-  // If we had a forward definition that has a type that disagrees with our
-  // initializer, insert a cast now.  This sort of thing occurs when we have a
-  // global union, and the LLVM type followed a union initializer that is
-  // different from the union element used for the type.
-  if (GV->getType()->getElementType() != Init->getType()) {
-    if (GV == Init) {
-      // Global initialized to its own address.
-      Init = TheFolder->CreateBitCast(Init, GV->getType()->getElementType());
-    } else {
-      GV->removeFromParent();
-      GlobalVariable *NGV = new GlobalVariable(*TheModule, Init->getType(),
-                                               GV->isConstant(),
-                                               GlobalValue::ExternalLinkage, 0,
-                                               GV->getName());
-      GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType()));
-      changeLLVMConstant(GV, NGV);
-      delete GV;
-      SET_DECL_LLVM(decl, NGV);
-      GV = NGV;
-    }
-  }
-
   // Set the initializer.
-  GV->setInitializer(Init);
+  if (GV->getType()->getElementType() == Init->getType()) {
+    GV->setInitializer(Init);
+  } else if (GV == Init && GV->getType()->getElementType()->isPointerTy()) {
+    // Global initialized to its own address, cast the address.
+    Init = TheFolder->CreateBitCast(Init, GV->getType()->getElementType());
+    GV->setInitializer(Init);
+  } else {
+    // If we had a forward definition that has a type that disagrees with our
+    // initializer, insert a cast now.  This sort of thing occurs when we have a
+    // global union, and the LLVM type followed a union initializer that is
+    // different from the union element used for the type.
+    GV->removeFromParent();
+    GlobalVariable *NGV = new GlobalVariable(*TheModule, Init->getType(),
+                                             GV->isConstant(),
+                                             GlobalValue::ExternalLinkage, 0,
+                                             GV->getName());
+    NGV->setInitializer(Init);
+    GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType()));
+    changeLLVMConstant(GV, NGV);
+    SET_DECL_LLVM(decl, NGV);
+    delete GV; // Frees Init if equal to GV.
+    GV = NGV;
+  }
 
   // Set thread local (TLS)
   if (isa<VAR_DECL>(decl) && DECL_THREAD_LOCAL_P(decl))

Added: dragonegg/trunk/test/validator/c/2012-05-06-SelfInit.c
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/validator/c/2012-05-06-SelfInit.c?rev=156267&view=auto
==============================================================================
--- dragonegg/trunk/test/validator/c/2012-05-06-SelfInit.c (added)
+++ dragonegg/trunk/test/validator/c/2012-05-06-SelfInit.c Sun May  6 14:35:11 2012
@@ -0,0 +1,4 @@
+// RUN: %dragonegg -S %s -o - | FileCheck %s
+#include <stdint.h>
+char *a = (void*)(uintptr_t)(void*)&a;
+// CHECK: @a = global i8* bitcast (i8** @a to i8*)





More information about the llvm-commits mailing list