[cfe-commits] r106103 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaTemplate/class-template-ctor-initializer.cpp
Douglas Gregor
dgregor at apple.com
Wed Jun 16 09:03:14 PDT 2010
Author: dgregor
Date: Wed Jun 16 11:03:14 2010
New Revision: 106103
URL: http://llvm.org/viewvc/llvm-project?rev=106103&view=rev
Log:
If a non-dependent base class initializer fails to match any direct or
virtual base class, but the class still has dependent base classes,
then don't diagnose the failed match as an error: the right base class
might magically appear. Fixes PR7259.
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaTemplate/class-template-ctor-initializer.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=106103&r1=106102&r2=106103&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 16 11:03:14 2010
@@ -1368,8 +1368,48 @@
for (unsigned i = 0; i < NumArgs; i++)
HasDependentArg |= Args[i]->isTypeDependent();
- SourceLocation BaseLoc = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin();
- if (BaseType->isDependentType() || HasDependentArg) {
+ SourceLocation BaseLoc
+ = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin();
+
+ if (!BaseType->isDependentType() && !BaseType->isRecordType())
+ return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
+ << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
+
+ // C++ [class.base.init]p2:
+ // [...] Unless the mem-initializer-id names a nonstatic data
+ // member of the constructorâs class or a direct or virtual base
+ // of that class, the mem-initializer is ill-formed. A
+ // mem-initializer-list can initialize a base class using any
+ // name that denotes that base class type.
+ bool Dependent = BaseType->isDependentType() || HasDependentArg;
+
+ // Check for direct and virtual base classes.
+ const CXXBaseSpecifier *DirectBaseSpec = 0;
+ const CXXBaseSpecifier *VirtualBaseSpec = 0;
+ if (!Dependent) {
+ FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
+ VirtualBaseSpec);
+
+ // C++ [base.class.init]p2:
+ // Unless the mem-initializer-id names a nonstatic data member of the
+ // constructor's class or a direct or virtual base of that class, the
+ // mem-initializer is ill-formed.
+ if (!DirectBaseSpec && !VirtualBaseSpec) {
+ // If the class has any dependent bases, then it's possible that
+ // one of those types will resolve to the same type as
+ // BaseType. Therefore, just treat this as a dependent base
+ // class initialization. FIXME: Should we try to check the
+ // initialization anyway? It seems odd.
+ if (ClassDecl->hasAnyDependentBases())
+ Dependent = true;
+ else
+ return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
+ << BaseType << Context.getTypeDeclType(ClassDecl)
+ << BaseTInfo->getTypeLoc().getLocalSourceRange();
+ }
+ }
+
+ if (Dependent) {
// Can't check initialization for a base of dependent type or when
// any of the arguments are type-dependent expressions.
OwningExprResult BaseInit
@@ -1389,23 +1429,6 @@
BaseInit.takeAs<Expr>(),
RParenLoc);
}
-
- if (!BaseType->isRecordType())
- return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
- << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
-
- // C++ [class.base.init]p2:
- // [...] Unless the mem-initializer-id names a nonstatic data
- // member of the constructorâs class or a direct or virtual base
- // of that class, the mem-initializer is ill-formed. A
- // mem-initializer-list can initialize a base class using any
- // name that denotes that base class type.
-
- // Check for direct and virtual base classes.
- const CXXBaseSpecifier *DirectBaseSpec = 0;
- const CXXBaseSpecifier *VirtualBaseSpec = 0;
- FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
- VirtualBaseSpec);
// C++ [base.class.init]p2:
// If a mem-initializer-id is ambiguous because it designates both
@@ -1414,14 +1437,6 @@
if (DirectBaseSpec && VirtualBaseSpec)
return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
<< BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
- // C++ [base.class.init]p2:
- // Unless the mem-initializer-id names a nonstatic data membeer of the
- // constructor's class ot a direst or virtual base of that class, the
- // mem-initializer is ill-formed.
- if (!DirectBaseSpec && !VirtualBaseSpec)
- return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
- << BaseType << Context.getTypeDeclType(ClassDecl)
- << BaseTInfo->getTypeLoc().getLocalSourceRange();
CXXBaseSpecifier *BaseSpec
= const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
Modified: cfe/trunk/test/SemaTemplate/class-template-ctor-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-ctor-initializer.cpp?rev=106103&r1=106102&r2=106103&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-ctor-initializer.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-ctor-initializer.cpp Wed Jun 16 11:03:14 2010
@@ -31,3 +31,25 @@
TmplB<char>() {}
};
+namespace PR7259 {
+ class Base {
+ public:
+ Base() {}
+ };
+
+ template <class ParentClass>
+ class Derived : public ParentClass {
+ public:
+ Derived() : Base() {}
+ };
+
+ class Final : public Derived<Base> {
+ };
+
+ int
+ main (void)
+ {
+ Final final();
+ return 0;
+ }
+}
More information about the cfe-commits
mailing list