summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
-rw-r--r--clang/test/SemaCXX/flexible-array-test.cpp4
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}}
+};
+
}
OpenPOWER on IntegriCloud