forked from OSchip/llvm-project
[CodeGen] Handle flexible array members containing pointers to members
Types can be classified as being zero-initializable or non-zero-initializable. We used to classify array types by giving them the classification of their base element type. However, incomplete array types are never initialized directly and thus are always zero-initializable. llvm-svn: 238256
This commit is contained in:
parent
c74f73f2a0
commit
67fa0b85cd
|
@ -1408,10 +1408,6 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
|
|||
|
||||
llvm::Constant *Element = EmitNullConstant(ElementTy);
|
||||
unsigned NumElements = CAT->getSize().getZExtValue();
|
||||
|
||||
if (Element->isNullValue())
|
||||
return llvm::ConstantAggregateZero::get(ATy);
|
||||
|
||||
SmallVector<llvm::Constant *, 8> Array(NumElements, Element);
|
||||
return llvm::ConstantArray::get(ATy, Array);
|
||||
}
|
||||
|
|
|
@ -153,15 +153,10 @@ struct CGRecordLowering {
|
|||
return CharUnits::fromQuantity(DataLayout.getABITypeAlignment(Type));
|
||||
}
|
||||
bool isZeroInitializable(const FieldDecl *FD) {
|
||||
const Type *Type = FD->getType()->getBaseElementTypeUnsafe();
|
||||
if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>())
|
||||
return Types.getCXXABI().isZeroInitializable(MPT);
|
||||
if (const RecordType *RT = Type->getAs<RecordType>())
|
||||
return isZeroInitializable(RT->getDecl());
|
||||
return true;
|
||||
return Types.isZeroInitializable(FD->getType());
|
||||
}
|
||||
bool isZeroInitializable(const RecordDecl *RD) {
|
||||
return Types.getCGRecordLayout(RD).isZeroInitializable();
|
||||
return Types.isZeroInitializable(RD);
|
||||
}
|
||||
void appendPaddingBytes(CharUnits Size) {
|
||||
if (!Size.isZero())
|
||||
|
|
|
@ -715,9 +715,16 @@ bool CodeGenTypes::isZeroInitializable(QualType T) {
|
|||
// No need to check for member pointers when not compiling C++.
|
||||
if (!Context.getLangOpts().CPlusPlus)
|
||||
return true;
|
||||
|
||||
T = Context.getBaseElementType(T);
|
||||
|
||||
|
||||
if (const auto *AT = Context.getAsArrayType(T)) {
|
||||
if (isa<IncompleteArrayType>(AT))
|
||||
return true;
|
||||
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
|
||||
if (Context.getConstantArrayElementCount(CAT) == 0)
|
||||
return true;
|
||||
T = Context.getBaseElementType(T);
|
||||
}
|
||||
|
||||
// Records are non-zero-initializable if they contain any
|
||||
// non-zero-initializable subobjects.
|
||||
if (const RecordType *RT = T->getAs<RecordType>()) {
|
||||
|
@ -733,6 +740,6 @@ bool CodeGenTypes::isZeroInitializable(QualType T) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CodeGenTypes::isZeroInitializable(const CXXRecordDecl *RD) {
|
||||
bool CodeGenTypes::isZeroInitializable(const RecordDecl *RD) {
|
||||
return getCGRecordLayout(RD).isZeroInitializable();
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ public: // These are internal details of CGT that shouldn't be used externally.
|
|||
|
||||
/// IsZeroInitializable - Return whether a record type can be
|
||||
/// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
|
||||
bool isZeroInitializable(const CXXRecordDecl *RD);
|
||||
bool isZeroInitializable(const RecordDecl *RD);
|
||||
|
||||
bool isRecordLayoutComplete(const Type *Ty) const;
|
||||
bool noRecordsBeingLaidOut() const {
|
||||
|
|
|
@ -277,4 +277,12 @@ U u;
|
|||
// CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
|
||||
}
|
||||
|
||||
namespace FlexibleArrayMember {
|
||||
struct S {
|
||||
int S::*x[];
|
||||
};
|
||||
S s;
|
||||
// CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
|
||||
}
|
||||
|
||||
// CHECK-O3: attributes [[NUW]] = { nounwind readnone{{.*}} }
|
||||
|
|
Loading…
Reference in New Issue