forked from OSchip/llvm-project
Fix "regression" caused by updating our notion of POD to better match the C++11
rules: instead of requiring flexible array members to be POD, require them to be trivially-destructible. This seems to be the only constraint that actually matters here (and even then, it's questionable whether this matters). llvm-svn: 198983
This commit is contained in:
parent
c26e63e986
commit
6fa28ffd5a
|
@ -3970,8 +3970,8 @@ def err_flexible_array_virtual_base : Error<
|
||||||
def err_flexible_array_empty_aggregate : Error<
|
def err_flexible_array_empty_aggregate : Error<
|
||||||
"flexible array member %0 not allowed in otherwise empty "
|
"flexible array member %0 not allowed in otherwise empty "
|
||||||
"%select{struct|interface|union|class|enum}1">;
|
"%select{struct|interface|union|class|enum}1">;
|
||||||
def err_flexible_array_has_nonpod_type : Error<
|
def err_flexible_array_has_nontrivial_dtor : Error<
|
||||||
"flexible array member %0 of non-POD element type %1">;
|
"flexible array member %0 of type %1 with non-trivial destruction">;
|
||||||
def ext_flexible_array_in_struct : Extension<
|
def ext_flexible_array_in_struct : Extension<
|
||||||
"%0 may not be nested in a struct due to flexible array member">,
|
"%0 may not be nested in a struct due to flexible array member">,
|
||||||
InGroup<FlexibleArrayExtensions>;
|
InGroup<FlexibleArrayExtensions>;
|
||||||
|
|
|
@ -11994,9 +11994,14 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
|
||||||
Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
|
Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
|
||||||
<< FD->getDeclName() << Record->getTagKind();
|
<< FD->getDeclName() << Record->getTagKind();
|
||||||
|
|
||||||
if (!FD->getType()->isDependentType() &&
|
// If the element type has a non-trivial destructor, we would not
|
||||||
!Context.getBaseElementType(FD->getType()).isPODType(Context)) {
|
// implicitly destroy the elements, so disallow it for now.
|
||||||
Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)
|
//
|
||||||
|
// FIXME: GCC allows this. We should probably either implicitly delete
|
||||||
|
// the destructor of the containing class, or just allow this.
|
||||||
|
QualType BaseElem = Context.getBaseElementType(FD->getType());
|
||||||
|
if (!BaseElem->isDependentType() && BaseElem.isDestructedType()) {
|
||||||
|
Diag(FD->getLocation(), diag::err_flexible_array_has_nontrivial_dtor)
|
||||||
<< FD->getDeclName() << FD->getType();
|
<< FD->getDeclName() << FD->getType();
|
||||||
FD->setInvalidDecl();
|
FD->setInvalidDecl();
|
||||||
EnclosingDecl->setInvalidDecl();
|
EnclosingDecl->setInvalidDecl();
|
||||||
|
|
|
@ -80,7 +80,7 @@ int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1];
|
||||||
|
|
||||||
struct FlexibleArrayMember0 {
|
struct FlexibleArrayMember0 {
|
||||||
int length;
|
int length;
|
||||||
id array[]; // expected-error{{flexible array member 'array' of non-POD element type 'id __strong[]'}}
|
id array[]; // expected-error{{flexible array member 'array' of type 'id __strong[]' with non-trivial destruction}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlexibleArrayMember1 {
|
struct FlexibleArrayMember1 {
|
||||||
|
|
|
@ -36,14 +36,20 @@ void foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
virtual void foo();
|
virtual void foo();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X {
|
struct X {
|
||||||
int blah;
|
int blah;
|
||||||
S strings[]; // expected-error {{flexible array member 'strings' of non-POD element type 'S []'}}
|
S strings[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
S a, b = a;
|
||||||
|
S f(X &x) {
|
||||||
|
a = b;
|
||||||
|
return x.strings[0];
|
||||||
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
int s;
|
int s;
|
||||||
char c[];
|
char c[];
|
||||||
|
@ -71,3 +77,14 @@ struct VirtStorage : virtual StorageBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NonTrivDtor { ~NonTrivDtor(); };
|
||||||
|
// FIXME: It's not clear whether we should disallow examples like this. GCC accepts.
|
||||||
|
struct FlexNonTrivDtor {
|
||||||
|
int n;
|
||||||
|
NonTrivDtor ntd[]; // expected-error {{flexible array member 'ntd' of type 'NonTrivDtor []' with non-trivial destruction}}
|
||||||
|
~FlexNonTrivDtor() {
|
||||||
|
for (int i = n; i != 0; --i)
|
||||||
|
ntd[i-1].~NonTrivDtor();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue