diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/flexible-array-test.cpp | 4 |
3 files changed, 16 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ae2d9c9e779..86108be0b93 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3937,6 +3937,9 @@ def ext_variable_sized_type_in_struct : ExtWarn< def ext_c99_flexible_array_member : Extension< "flexible array members are a C99 feature">, InGroup<C99>; +def err_flexible_array_virtual_base : Error< + "flexible array member %0 not allowed in " + "%select{struct|interface|union|class|enum}1 which has a virtual base class">; def err_flexible_array_empty_aggregate : Error< "flexible array member %0 not allowed in otherwise empty " "%select{struct|interface|union|class|enum}1 is not allowed">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 101f4ce8988..d9dd4507de6 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11841,6 +11841,15 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (DiagID) Diag(FD->getLocation(), DiagID) << FD->getDeclName() << Record->getTagKind(); + // While the layout of types that contain virtual bases is not specified + // by the C++ standard, both the Itanium and Microsoft C++ ABIs place + // virtual bases after the derived members. This would make a flexible + // array member declared at the end of an object not adjacent to the end + // of the type. + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) + if (RD->getNumVBases() != 0) + Diag(FD->getLocation(), diag::err_flexible_array_virtual_base) + << FD->getDeclName() << Record->getTagKind(); if (!getLangOpts().C99) Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) << FD->getDeclName() << Record->getTagKind(); diff --git a/clang/test/SemaCXX/flexible-array-test.cpp b/clang/test/SemaCXX/flexible-array-test.cpp index e6c3132801f..f287711eeb6 100644 --- a/clang/test/SemaCXX/flexible-array-test.cpp +++ b/clang/test/SemaCXX/flexible-array-test.cpp @@ -66,4 +66,8 @@ struct Storage : StorageBase { int data[]; }; +struct VirtStorage : virtual StorageBase { + int data[]; // expected-error {{flexible array member 'data' not allowed in struct which has a virtual base class}} +}; + } |