LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 162 - [llvmgcc] Global unions initialization does not work in all cases
Summary: [llvmgcc] Global unions initialization does not work in all cases
Status: RESOLVED FIXED
Alias: None
Product: tools
Classification: Unclassified
Component: llvm-gcc (show other bugs)
Version: 1.0
Hardware: All All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords: compile-fail
: 156 650 (view as bug list)
Depends on:
Blocks: 156 199
  Show dependency tree
 
Reported: 2003-12-03 14:48 PST by John T. Criswell
Modified: 2010-02-22 12:45 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John T. Criswell 2003-12-03 14:48:50 PST
The GCC front end hits an assertion when compiling
llvm/test/Regression/CFrontend/2003-01-30-UnionInit.c (named test.c in the
following sample output):

cc1: ../../src/gcc/llvm-expand.c:4679: llvm_expand_constant_expr: Assertion `0
&& "Couldn't expand constructor in this context!"' failed.
test.c:8: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://llvm.cs.uiuc.edu> for instructions.
Comment 1 John T. Criswell 2003-12-03 14:57:00 PST
Note that this bug seems to prevent LLVM GCC from compiling on Sparc, so I'm
moving the milestone.

The problem seems to occur because we use the same code to initialize structures
and unions.  This is not correct as unions can only initialize the first union
member while structures can initialize all of their struct members.  This causes
us to attempt to initialize the wrong union member, get type mismatches, and hit
the assertion.

I've hacked up a patch that seems to more or less work (but may not totally be
correct or may break other tests).  If it works well enough, I'll attach it.
Comment 2 John T. Criswell 2003-12-03 17:13:51 PST
My proposed patch fixes GCC so that it can build on Sparc again, but it produces
new bugs.

After further investigation, I found the following:

1. GCC can initialize any arbitrary member of a union.
2. It appears that the LLVM GCC front end creates structures with a single
member for unions.  That member is the largest member of the union.
3. llvm-gcc uses a member's position to determine its type based upon the LLVM
created type.  This works for struct's which have a 1-1 correspondance, but not
for unions.

I believe the second and third points are the cause of the problem.  The failing
union is:
union foo {
  struct { char A, B; } X;
  int C;
};
union foo V = { {1, 2} };

llvm-gcc converts this union to a structure with one integer member.  When
trying to initalize member X, it looks into this LLVM stucture for the first
member, which is an int (the largest member).  It then tries to initalize the
int with a struct, which fails.

Comment 3 John T. Criswell 2003-12-04 14:41:41 PST
I belive this summary describes the problem a little more precisely:

Unions in C/C++ are reduced to an LLVM structure containing the largest member.
 An LLVM global variable of this type cannot be initialized by any union member
other than the largest member (otherwise, a type mismatch results).  Casting
doesn't seem to solve the problem since some types cannot be casted into others.
Comment 4 Chris Lattner 2003-12-04 16:52:51 PST
Unfortunately, there isn't really any way to fix this without a substantial
rewrite of the initializer handling code.  I was planning on doing this after 1.1...

-Chris
Comment 5 Chris Lattner 2003-12-06 19:54:00 PST
Ugh.  I looked into this more, and this is _precisely_ the case that I need to
do the rewrite for.  I wonder, where does this union initialization come from in
the C front-end?  It might be better to hack the source in the C front-end to
temporarily work around this problem if possible.  If you point it out, I can
figure out the appropriate work-around.

I changed the subject line to be a bit more amorphous, because there are other
cases that don't work either, involving nested unions and other crimes against
nature.

-Chris
Comment 6 Chris Lattner 2004-03-08 18:34:37 PST
perhaps next release
Comment 7 Chris Lattner 2005-11-03 00:30:47 PST
*** Bug 650 has been marked as a duplicate of this bug. ***
Comment 8 Chris Lattner 2005-11-03 00:33:05 PST
*** Bug 156 has been marked as a duplicate of this bug. ***
Comment 9 Chris Lattner 2005-11-03 00:51:40 PST
When working on this bug, please make sure that all of the marked duplicates are fixed before this one is 
closed.

-Chris
Comment 10 Chris Lattner 2006-01-24 14:28:32 PST
Testcase here: llvm-test/SingleSource/UnitTests/2006-01-23-UnionInit.c
This is fixed by the new frontend and will be closed when it is the default.

-Chris
Comment 11 Chris Lattner 2006-08-05 18:16:29 PDT
This is fixed in llvmgcc4.