g++ is more permissive regarding flexible arrays.

It will accept flexible array in union and also as the sole element of a struct/class.

Fixes rdar://9065507.

llvm-svn: 127171
This commit is contained in:
Argyrios Kyrtzidis 2011-03-07 20:04:04 +00:00
parent e5d7369e1e
commit 7e25a95600
3 changed files with 34 additions and 8 deletions

View File

@ -2288,12 +2288,17 @@ def ext_flexible_array_in_array : Extension<
"%0 may not be used as an array element due to flexible array member">; "%0 may not be used as an array element due to flexible array member">;
def err_flexible_array_init_nonempty : Error< def err_flexible_array_init_nonempty : Error<
"non-empty initialization of flexible array member inside subobject">; "non-empty initialization of flexible array member inside subobject">;
def ext_flexible_array_empty_aggregate : Extension< def ext_flexible_array_empty_aggregate_ms : Extension<
"flexible array member %0 in otherwise empty %select{struct|class}1 " "flexible array member %0 in otherwise empty %select{struct|class}1 "
"is a Microsoft extension">, InGroup<Microsoft>; "is a Microsoft extension">, InGroup<Microsoft>;
def ext_flexible_array_union : Extension< def ext_flexible_array_union_ms : Extension<
"flexible array member %0 in a union is a Microsoft extension">, "flexible array member %0 in a union is a Microsoft extension">,
InGroup<Microsoft>; InGroup<Microsoft>;
def ext_flexible_array_empty_aggregate_gnu : Extension<
"flexible array member %0 in otherwise empty %select{struct|class}1 "
"is a GNU extension">, InGroup<GNU>;
def ext_flexible_array_union_gnu : Extension<
"flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
def err_flexible_array_init_needs_braces : Error< def err_flexible_array_init_needs_braces : Error<
"flexible array requires brace-enclosed initializer">; "flexible array requires brace-enclosed initializer">;

View File

@ -7374,20 +7374,27 @@ void Sema::ActOnFields(Scope* S,
continue; continue;
} else if (FDTy->isIncompleteArrayType() && Record && } else if (FDTy->isIncompleteArrayType() && Record &&
((i == NumFields - 1 && !Record->isUnion()) || ((i == NumFields - 1 && !Record->isUnion()) ||
(getLangOptions().Microsoft && ((getLangOptions().Microsoft || getLangOptions().CPlusPlus) &&
(i == NumFields - 1 || Record->isUnion())))) { (i == NumFields - 1 || Record->isUnion())))) {
// Flexible array member. // Flexible array member.
// Microsoft is more permissive regarding flexible array. // Microsoft and g++ is more permissive regarding flexible array.
// It will accept flexible array in union and also // It will accept flexible array in union and also
// as the sole element of a struct/class. // as the sole element of a struct/class.
if (getLangOptions().Microsoft) { if (getLangOptions().Microsoft) {
if (Record->isUnion()) if (Record->isUnion())
Diag(FD->getLocation(), diag::ext_flexible_array_union) Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
<< FD->getDeclName(); << FD->getDeclName();
else if (NumFields == 1) else if (NumFields == 1)
Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate) Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms)
<< FD->getDeclName() << Record->getTagKind(); << FD->getDeclName() << Record->getTagKind();
} else if (NumNamedMembers < 1) { } else if (getLangOptions().CPlusPlus) {
if (Record->isUnion())
Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
<< FD->getDeclName();
else if (NumFields == 1)
Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu)
<< FD->getDeclName() << Record->getTagKind();
} else if (NumNamedMembers < 1) {
Diag(FD->getLocation(), diag::err_flexible_array_empty_struct) Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
<< FD->getDeclName(); << FD->getDeclName();
FD->setInvalidDecl(); FD->setInvalidDecl();

View File

@ -51,5 +51,19 @@ class A {
union B { union B {
int s; int s;
char c[]; // expected-error {{field has incomplete type 'char []'}} char c[];
}; };
namespace rdar9065507 {
struct StorageBase {
long ref_count;
unsigned size;
unsigned capacity;
};
struct Storage : StorageBase {
int data[];
};
}