]> granicus.if.org Git - clang/commitdiff
Sema: Disallow inheriting from classes with flexible array members
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 2 Nov 2013 12:00:36 +0000 (12:00 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 2 Nov 2013 12:00:36 +0000 (12:00 +0000)
Flexible array members inherently index off of the end of their parent
type.

We shouldn't allow this type to be used as a base, virtual or otherwise,
because indexing off the end may find us inside of another base or the
derived types members.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193923 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp

index ef78cc9c168316330a031775de0f8a095e157f72..092d5844f6ac6d604cb87b02e33eb2866180a491 100644 (file)
@@ -5885,6 +5885,8 @@ def err_base_must_be_class : Error<"base specifier must name a class">;
 def err_union_as_base_class : Error<"unions cannot be base classes">;
 def err_circular_inheritance : Error<
   "circular inheritance between %0 and %1">;
+def err_base_class_has_flexible_array_member : Error<
+  "base class %0 has a flexible array member">;
 def err_incomplete_base_class : Error<"base class has incomplete type">;
 def err_duplicate_base_class : Error<
   "base class %0 specified more than once as a direct base class">;
index dce0592592a51ad20a76840990c4837afb978e5b..c8338353ea93ed5ac7092f7aefb8a26bcd10b31a 100644 (file)
@@ -1370,6 +1370,18 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
   assert(CXXBaseDecl && "Base type is not a C++ type");
 
+  // A class which contains a flexible array member is not suitable for use as a
+  // base class:
+  //   - If the layout determines that a base comes before another base,
+  //     the flexible array member would index into the subsequent base.
+  //   - If the layout determines that base comes before the derived class,
+  //     the flexible array member would index into the derived class.
+  if (CXXBaseDecl->hasFlexibleArrayMember()) {
+    Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
+      << CXXBaseDecl->getDeclName();
+    return 0;
+  }
+
   // C++ [class]p3:
   //   If a class is marked final and it appears as a base-type-specifier in
   //   base-clause, the program is ill-formed.