Make sure we correctly zero-initialize unions containing a pointer to data member as the first field. PR11487.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146009 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2011-12-07 01:30:11 +00:00
Родитель dcf06fa1fb
Коммит 26e80cdfe8
3 изменённых файлов: 27 добавлений и 7 удалений

Просмотреть файл

@ -1244,14 +1244,18 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
E = record->field_end(); I != E; ++I) { E = record->field_end(); I != E; ++I) {
const FieldDecl *field = *I; const FieldDecl *field = *I;
// Ignore bit fields. // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
if (field->isBitField()) // will fill in later.)
continue; if (!field->isBitField()) {
unsigned fieldIndex = layout.getLLVMFieldNo(field); unsigned fieldIndex = layout.getLLVMFieldNo(field);
elements[fieldIndex] = CGM.EmitNullConstant(field->getType()); elements[fieldIndex] = CGM.EmitNullConstant(field->getType());
} }
// For unions, stop after the first named field.
if (record->isUnion() && field->getDeclName())
break;
}
// Fill in the virtual bases, if we're working with the complete object. // Fill in the virtual bases, if we're working with the complete object.
if (asCompleteObject) { if (asCompleteObject) {
for (CXXRecordDecl::base_class_const_iterator for (CXXRecordDecl::base_class_const_iterator

Просмотреть файл

@ -531,6 +531,7 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
CharUnits unionAlign = CharUnits::Zero(); CharUnits unionAlign = CharUnits::Zero();
bool hasOnlyZeroSizedBitFields = true; bool hasOnlyZeroSizedBitFields = true;
bool checkedFirstFieldZeroInit = false;
unsigned fieldNo = 0; unsigned fieldNo = 0;
for (RecordDecl::field_iterator field = D->field_begin(), for (RecordDecl::field_iterator field = D->field_begin(),
@ -542,6 +543,11 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
if (!fieldType) if (!fieldType)
continue; continue;
if (field->getDeclName() && !checkedFirstFieldZeroInit) {
CheckZeroInitializable(field->getType());
checkedFirstFieldZeroInit = true;
}
hasOnlyZeroSizedBitFields = false; hasOnlyZeroSizedBitFields = false;
CharUnits fieldAlign = CharUnits::fromQuantity( CharUnits fieldAlign = CharUnits::fromQuantity(

Просмотреть файл

@ -230,3 +230,13 @@ namespace test4 {
// CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8 // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
D d; D d;
} }
namespace PR11487 {
union U
{
int U::* mptr;
char x[16];
} x;
// CHECK-GLOBAL: @_ZN7PR114871xE = global %"union.PR11487::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
}