Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[llvmgcc] Global unions initialization does not work in all cases #534

Closed
llvmbot opened this issue Dec 3, 2003 · 12 comments
Closed

[llvmgcc] Global unions initialization does not work in all cases #534

llvmbot opened this issue Dec 3, 2003 · 12 comments

Comments

@llvmbot
Copy link
Collaborator

@llvmbot llvmbot commented Dec 3, 2003

Bugzilla Link 162
Resolution FIXED
Resolved on Feb 22, 2010 12:45
Version 1.0
OS All
Blocks #528 llvm/llvm-bugzilla-archive#199
Reporter LLVM Bugzilla Contributor

Extended Description

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.

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 3, 2003

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.

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 4, 2003

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.

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Dec 4, 2003

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.

@lattner
Copy link
Collaborator

@lattner lattner commented Dec 5, 2003

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

@lattner
Copy link
Collaborator

@lattner lattner commented Dec 7, 2003

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

@lattner
Copy link
Collaborator

@lattner lattner commented Mar 9, 2004

perhaps next release

@lattner
Copy link
Collaborator

@lattner lattner commented Nov 3, 2005

*** Bug llvm/llvm-bugzilla-archive#650 has been marked as a duplicate of this bug. ***

@lattner
Copy link
Collaborator

@lattner lattner commented Nov 3, 2005

*** Bug #528 has been marked as a duplicate of this bug. ***

@lattner
Copy link
Collaborator

@lattner lattner commented Nov 3, 2005

When working on this bug, please make sure that all of the marked duplicates are fixed before this one is
closed.

-Chris

@lattner
Copy link
Collaborator

@lattner lattner commented Jan 24, 2006

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

@lattner
Copy link
Collaborator

@lattner lattner commented Aug 6, 2006

This is fixed in llvmgcc4.

@llvmbot
Copy link
Collaborator Author

@llvmbot llvmbot commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#199

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 1, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants