-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
apparent union bug #3052
Comments
This works for me on x86-32 Darwin. It could be related to 54503. Is your llvm-gcc up to date as well as llvm? If it is, could you post the assembly code here? |
Yes my llvm-gcc is from today. Files attached, hope this helps. |
This is a cute one; I suppose the good news is that this has nothing to do with 54503. The code is copying 2140832546U == 0x7f9a8322 by |
So is this PR invalid? |
Not at all. The active element of the union at the time it's copied is a pointer, and we therefore can't use floating point operations to copy it (at least on x87). It is probably an easy fix in the llvm-gcc FE to do a bitwise copy (memcpy) instead in this case (returning a value). However, I'm concerned this might be a symptom of a more widespread problem. The IR represents this type as |
Thoughts: (1) if I bitcast a float* to an int*, then store to it, |
proposed patch |
Re (2), the C struct cjt5 has holes in it; the LLVM IR type of that name does not. I don't know how the converter constructs a type to represent a union (except that it must be the same size and alignment as the real union). |
Yep, looks good. I'll do more extensive testing over the weekend. |
Should be fixed here (somewhat more restrictive patch). |
Extended Description
This is seen on r54780 on Ubuntu Feisty on ia32. Removing any field of cjt5 makes the problem go away.
[regehr@babel tmp8]$ llvm-gcc -O -Wall small.c -o small ; ./small
small: small.c:26: main: Assertion `cj41.cj35 == cj43.cj35' failed.
Aborted (core dumped)
[regehr@babel tmp8]$ cat small.c
#include <assert.h>
union cjt7
{
double *cj35;
struct cjt5 {
float cj27;
signed int cj29:7;
signed int cj30:7;
signed int cj31:5;
} cj37;
};
union cjt7 cj41 = {
(double *) 2140832546U,
};
union cjt7 callee_cj0f(void)
{
return cj41;
}
int main(void)
{
union cjt7 cj43 = callee_cj0f();
assert(cj41.cj35 == cj43.cj35);
return 0;
}
The text was updated successfully, but these errors were encountered: