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">;
|
"%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">;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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[];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue