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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193920 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 101f4ce..d9dd450 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11841,6 +11841,15 @@
       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();