Philip Guo
2009-Feb-19 04:20 UTC
[LLVMdev] what's correct behavior for struct forward declarations?
hi all, i'm trying to use LLVM to compile some linux kernel code, and i noticed a mismatch with gcc. here is a simplified test case: struct foo { int a; int b; int c; }; static struct foo x; // 'forward' declaration? int bar() { printf("a: %d, b: %d, c: %d\n", x.a, x.b, x.c); } static struct foo x = { .a = 1, .b = 2, .c = 3, }; int main() { bar(); return 0; } when this code is compiled with gcc and run, stdout prints "a: 1, b: 2, c: 3", which means that it takes the true declaration of x, initialized to 1, 2, 3. however, when it's compiled with llvm, llvm emits the following code for x: @x = internal global %struct.foo zeroinitializer ; <%struct.foo*> [#uses=3] which seems to me like it's taking the first declaration of x, which is a forward declaration. is that the correct behavior? i believe that the kernel developers intended for the second (real declaration) of x to be visible, even in bar(), but that's not what's happening with llvm. is there an easy workaround where i can get llvm to emit code initializing x to {1,2,3}? thanks! Philip -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090218/2f65fc21/attachment.html>
Chris Lattner
2009-Feb-19 04:30 UTC
[LLVMdev] what's correct behavior for struct forward declarations?
On Feb 18, 2009, at 8:20 PM, Philip Guo wrote:> hi all, > > i'm trying to use LLVM to compile some linux kernel code, and i > noticed a mismatch with gcc. here is a simplified test case:This definitely looks like a bug, but I can't reproduce it with mainline. Are you sure this is not fixed with SVN? -Chris> > > struct foo { > int a; > int b; > int c; > }; > > static struct foo x; // 'forward' declaration? > > int bar() { > printf("a: %d, b: %d, c: %d\n", x.a, x.b, x.c); > } > > static struct foo x = { > .a = 1, .b = 2, .c = 3, > }; > > int main() { > bar(); > return 0; > } > > > when this code is compiled with gcc and run, stdout prints "a: 1, b: > 2, c: 3", which means that it takes the true declaration of x, > initialized to 1, 2, 3. however, when it's compiled with llvm, llvm > emits the following code for x: > > @x = internal global %struct.foo zeroinitializer ; <%struct.foo*> > [#uses=3] > > which seems to me like it's taking the first declaration of x, which > is a forward declaration. is that the correct behavior? i believe > that the kernel developers intended for the second (real > declaration) of x to be visible, even in bar(), but that's not > what's happening with llvm. is there an easy workaround where i can > get llvm to emit code initializing x to {1,2,3}? thanks! > > Philip > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev