From 7e25a95600fe31c47125bca36d0553915658d8af Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 7 Mar 2011 20:04:04 +0000 Subject: [PATCH] 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 --- .../include/clang/Basic/DiagnosticSemaKinds.td | 9 +++++++-- clang/lib/Sema/SemaDecl.cpp | 17 ++++++++++++----- clang/test/SemaCXX/flexible-array-test.cpp | 16 +++++++++++++++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d7a1c387ac81..ba439513a49b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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; -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; +def ext_flexible_array_empty_aggregate_gnu : Extension< + "flexible array member %0 in otherwise empty %select{struct|class}1 " + "is a GNU extension">, InGroup; +def ext_flexible_array_union_gnu : Extension< + "flexible array member %0 in a union is a GNU extension">, InGroup; def err_flexible_array_init_needs_braces : Error< "flexible array requires brace-enclosed initializer">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0e114eaa864f..b6191e82cd25 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7374,20 +7374,27 @@ 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 (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) << FD->getDeclName(); FD->setInvalidDecl(); diff --git a/clang/test/SemaCXX/flexible-array-test.cpp b/clang/test/SemaCXX/flexible-array-test.cpp index 95d8bb1aa413..e6c3132801f8 100644 --- a/clang/test/SemaCXX/flexible-array-test.cpp +++ b/clang/test/SemaCXX/flexible-array-test.cpp @@ -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[]; +}; + +}