r193920 - Sema: Disallow derived classes with virtual bases from having flexible array members

David Majnemer david.majnemer at gmail.com
Sat Nov 2 04:19:14 PDT 2013


Author: majnemer
Date: Sat Nov  2 06:19:13 2013
New Revision: 193920

URL: http://llvm.org/viewvc/llvm-project?rev=193920&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/flexible-array-test.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=193920&r1=193919&r2=193920&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Nov  2 06:19:13 2013
@@ -3937,6 +3937,9 @@ def ext_variable_sized_type_in_struct :
 
 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">;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=193920&r1=193919&r2=193920&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Nov  2 06:19:13 2013
@@ -11841,6 +11841,15 @@ void Sema::ActOnFields(Scope *S, SourceL
       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();

Modified: cfe/trunk/test/SemaCXX/flexible-array-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/flexible-array-test.cpp?rev=193920&r1=193919&r2=193920&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/flexible-array-test.cpp (original)
+++ cfe/trunk/test/SemaCXX/flexible-array-test.cpp Sat Nov  2 06:19:13 2013
@@ -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}}
+};
+
 }





More information about the cfe-commits mailing list