Open Quuxplusone opened 12 years ago
Bugzilla Link | PR11742 |
Status | NEW |
Importance | P enhancement |
Reported by | Richard Smith (richard-llvm@metafoo.co.uk) |
Reported on | 2012-01-10 22:59:38 -0800 |
Last modified on | 2012-12-09 02:49:41 -0800 |
Version | unspecified |
Hardware | PC Linux |
CC | baldrick@free.fr, dgregor@apple.com, llvm-bugs@lists.llvm.org, nlewycky@google.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
A testcase or three would be nice.
Simple example:
struct S { char c = 1; __attribute__((aligned(8))) char d = 2; } s = S();
char k = ((char*)&s)[1] + 1;
... gives ...
@s = global %struct.S { i8 1, [7 x i8] undef, i8 2, [7 x i8] undef }, align 8
... which is wrong. The padding should be zeroed. Running this through opt -
instcombine -globalopt gives:
@k = global i8 undef, align 1
... which is wrong. k should be 1.
(Running this through just opt -globalopt strangely gives
@k = global i8 1, align 1
which Nick tells me is a bug in globalopt.)
If the C++11 standard really says that *padding* must be initialized to zero
(your point 2) then indeed using undef is simply wrong.
(In reply to comment #3)
> If the C++11 standard really says that *padding* must be initialized to zero
> (your point 2) then indeed using undef is simply wrong.
It really does. C++11 [dcl.init]p6:
"To zero-initialize an object or reference of type T means:
— if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;
— if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
— if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed."
I partially fixed this in dragonegg in commit 169678. There remains the case
of something like this
A : char;
B : int;
which has implicit padding between A and B due to B's natural alignment. Must
this kind of padding also be zero initialized? Note that this is different to
your test case in a sense, though not so much in spirit.
I'm not sure what your notation means, but if you mean something like 'struct S { char A; int B; };', then yes, if an object of type S is zero-initialized, the padding between fields must be initialized to zero bits.
In Clang at least, such a struct is emitted as 'global %struct.S { i8 1, i32 2 }'. It's not clear to me whether the padding is zero or undef in this case.
I'm pretty sure the padding is "undef" in this case.