зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
dcf06fa1fb
Коммит
26e80cdfe8
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче