summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-11-02 11:19:13 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-11-02 11:19:13 +0000
commit08cd76006fda60d8f006071ade1e16025f349287 (patch)
tree44036a07473f1033ec02166826776fd0e6f58698
parent4101621dd7463226941602e007c3da1d4012f8ed (diff)
downloadbcm5719-llvm-08cd76006fda60d8f006071ade1e16025f349287.tar.gz
bcm5719-llvm-08cd76006fda60d8f006071ade1e16025f349287.zip
Sema: Disallow derived classes with virtual bases from having flexible array members
Flexible array members only work out if they are the last field of a record, however virtual bases would give us many situations where the flexible array member would overlap with the virtual base fields. It is unlikely in the extreme that this behavior was intended by the user so raise a diagnostic instead of accepting. This is will not reject conforming code because flexible array members are an extension in C++ mode. llvm-svn: 193920
-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