forked from OSchip/llvm-project
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:
parent
e5d7369e1e
commit
7e25a95600
|
@ -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">;
|
||||
def err_flexible_array_init_nonempty : Error<
|
||||
"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 "
|
||||
"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">,
|
||||
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<
|
||||
"flexible array requires brace-enclosed initializer">;
|
||||
|
|
|
@ -7374,18 +7374,25 @@ void Sema::ActOnFields(Scope* S,
|
|||
continue;
|
||||
} else if (FDTy->isIncompleteArrayType() && Record &&
|
||||
((i == NumFields - 1 && !Record->isUnion()) ||
|
||||
(getLangOptions().Microsoft &&
|
||||
((getLangOptions().Microsoft || getLangOptions().CPlusPlus) &&
|
||||
(i == NumFields - 1 || Record->isUnion())))) {
|
||||
// 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
|
||||
// as the sole element of a struct/class.
|
||||
if (getLangOptions().Microsoft) {
|
||||
if (Record->isUnion())
|
||||
Diag(FD->getLocation(), diag::ext_flexible_array_union)
|
||||
Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
|
||||
<< FD->getDeclName();
|
||||
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();
|
||||
} 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)
|
||||
|
|
|
@ -51,5 +51,19 @@ class A {
|
|||
|
||||
union B {
|
||||
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[];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue