From 28165b7a977339253ce34b7b1b1c442b9b73f46d Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 2 Nov 2013 12:00:36 +0000 Subject: [PATCH] Sema: Disallow inheriting from classes with flexible array members 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 | 2 ++ lib/Sema/SemaDeclCXX.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index ef78cc9c16..092d5844f6 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index dce0592592..c8338353ea 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1370,6 +1370,18 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, CXXRecordDecl *CXXBaseDecl = cast(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. -- 2.40.0