[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