]> granicus.if.org Git - clang/commitdiff
Don't try to initialize a reference with a constructed temporary if either
authorJohn McCall <rjmccall@apple.com>
Tue, 17 Aug 2010 07:23:57 +0000 (07:23 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 17 Aug 2010 07:23:57 +0000 (07:23 +0000)
of the classes is invalid.  A class is invalid if a base is invalid.

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

lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaInit.cpp
test/SemaCXX/constructor-initializer.cpp

index 1d0b4a9450f89e8887b50ae408e74595720998cf..3f59fb71d01c6d9477118a6c860eeb5967ce6c16 100644 (file)
@@ -483,8 +483,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   //   defined class.
   if (RequireCompleteType(BaseLoc, BaseType,
                           PDiag(diag::err_incomplete_base_class)
-                            << SpecifierRange))
+                            << SpecifierRange)) {
+    Class->setInvalidDecl();
     return 0;
+  }
 
   // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
   RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl();
@@ -503,6 +505,9 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   }
 
   SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
+
+  if (BaseDecl->isInvalidDecl())
+    Class->setInvalidDecl();
   
   // Create the base specifier.
   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
index e1fcab0c4008b4f5c1e9ab7f30afb62d3a7e7815..13ba8ee5f9700a4c72b69130068deb06dbf2ab4d 100644 (file)
@@ -2306,6 +2306,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
     // The type we're converting to is a class type. Enumerate its constructors
     // to see if there is a suitable conversion.
     CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+
     DeclContext::lookup_iterator Con, ConEnd;
     for (llvm::tie(Con, ConEnd) = S.LookupConstructors(T1RecordDecl);
          Con != ConEnd; ++Con) {
@@ -2333,6 +2334,8 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
       }
     }    
   }
+  if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
   const RecordType *T2RecordType = 0;
   if ((T2RecordType = T2->getAs<RecordType>()) &&
@@ -2380,6 +2383,8 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
       }
     }
   }
+  if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
   SourceLocation DeclLoc = Initializer->getLocStart();
 
index cf309f5597d33ce068d4cc9e9ebc2009aea96d56..31d53302bf4727275e4f9f9b7cd40930ab01dc36 100644 (file)
@@ -221,3 +221,17 @@ namespace PR7402 {
     S s(3);
   }
 }
+
+// <rdar://problem/8308215>: don't crash.
+// Lots of questionable recovery here;  errors can change.
+namespace test3 {
+  class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 3 {{candidate}} expected-note {{passing argument}}
+  class B : public A {
+  public:
+    B(const String& s, int e=0) // expected-error {{unknown type name}} 
+      : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
+    B(const B& e)
+      : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{no viable conversion}} expected-error {{does not name}}
+    }
+  };
+}