[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