From: Eli Friedman Date: Sat, 5 Dec 2009 23:03:49 +0000 (+0000) Subject: Fix for PR5693: shift some code into SetClassDeclAttributesFromBase so that X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d013733c73507674b5db55d1686339e45c9e6edf;p=clang Fix for PR5693: shift some code into SetClassDeclAttributesFromBase so that it gets called during template instantiation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90682 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 992bb80189..652b92db5e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -484,10 +484,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, assert(BaseDecl && "Base type is not incomplete, but has no definition"); CXXRecordDecl * CXXBaseDecl = cast(BaseDecl); assert(CXXBaseDecl && "Base type is not a C++ type"); - if (!CXXBaseDecl->isEmpty()) - Class->setEmpty(false); - if (CXXBaseDecl->isPolymorphic()) - Class->setPolymorphic(true); + // C++0x CWG Issue #817 indicates that [[final]] classes shouldn't be bases. if (CXXBaseDecl->hasAttr()) { Diag(BaseLoc, diag::err_final_base) << BaseType.getAsString(); @@ -496,7 +493,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, return 0; } - SetClassDeclAttributesFromBase(Class, cast(BaseDecl), Virtual); + SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual); // Create the base specifier. // FIXME: Allocate via ASTContext? @@ -508,10 +505,23 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class, const CXXRecordDecl *BaseClass, bool BaseIsVirtual) { + // A class with a non-empty base class is not empty. + // FIXME: Standard ref? + if (!BaseClass->isEmpty()) + Class->setEmpty(false); + + // C++ [class.virtual]p1: + // A class that [...] inherits a virtual function is called a polymorphic + // class. + if (BaseClass->isPolymorphic()) + Class->setPolymorphic(true); // C++ [dcl.init.aggr]p1: // An aggregate is [...] a class with [...] no base classes [...]. Class->setAggregate(false); + + // C++ [class]p4: + // A POD-struct is an aggregate class... Class->setPOD(false); if (BaseIsVirtual) { diff --git a/test/SemaTemplate/template-class-traits.cpp b/test/SemaTemplate/template-class-traits.cpp new file mode 100644 index 0000000000..7cf2004e72 --- /dev/null +++ b/test/SemaTemplate/template-class-traits.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s +#define T(b) (b) ? 1 : -1 +#define F(b) (b) ? -1 : 1 + +struct HasVirt { virtual void a(); }; +template struct InheritPolymorph : HasVirt {}; +int t01[T(__is_polymorphic(InheritPolymorph))]; +