]> granicus.if.org Git - clang/commitdiff
Make sure to call CompleteConstructorCall for bases and members that are initialized...
authorAnders Carlsson <andersca@mac.com>
Thu, 29 Oct 2009 15:46:07 +0000 (15:46 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 29 Oct 2009 15:46:07 +0000 (15:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85510 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaTemplate/default-expr-arguments.cpp

index 11a39385443df688c4530fbd1b8ea6811be3bea7..f89b7a79525831cc14fab05f1217785ba5ccae49 100644 (file)
@@ -2304,7 +2304,7 @@ public:
                                      SourceLocation RParenLoc,
                                      CXXRecordDecl *ClassDecl);
 
-  void setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+  void SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
                               CXXBaseOrMemberInitializer **Initializers,
                               unsigned NumInitializers,
                               llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
index 2ba1130c87518e1f4493af463d605d33677d33cd..71afe6891661159c6d71de8749498eb44608b640 100644 (file)
@@ -3769,6 +3769,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
 }
 
 Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+  // Clear the last template instantiation error context.
+  LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
+  
   if (!D)
     return D;
   FunctionDecl *FD = 0;
index 01ab0a7241dc157e5e074ec69a15fdb46cb8f13b..90aef21637319904e4187957aa277c9bfadf2568 100644 (file)
@@ -1123,7 +1123,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
 }
 
 void
-Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
                               CXXBaseOrMemberInitializer **Initializers,
                               unsigned NumInitializers,
                               llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
@@ -1179,7 +1179,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
           AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
         CXXRecordDecl *BaseDecl =
           cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
-        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+        assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
         if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
           MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
         AllToInit.push_back(Value);
@@ -1187,18 +1187,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
       else {
         CXXRecordDecl *VBaseDecl =
         cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
-        assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
+        assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl null");
         CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
-        if (!Ctor)
+        if (!Ctor) {
           Bases.push_back(VBase);
-        else
-          MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+          continue;
+        }
 
+        ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+        if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0), 
+                                    Constructor->getLocation(), CtorArgs))
+          continue;
+        
+        MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+        
         CXXBaseOrMemberInitializer *Member =
-        new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
-                                    Ctor,
-                                    SourceLocation(),
-                                    SourceLocation());
+          new (Context) CXXBaseOrMemberInitializer(VBase->getType(),
+                                                   CtorArgs.takeAs<Expr>(),
+                                                   CtorArgs.size(), Ctor,
+                                                   SourceLocation(),
+                                                   SourceLocation());
         AllToInit.push_back(Member);
       }
     }
@@ -1216,7 +1224,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
           AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
         CXXRecordDecl *BaseDecl =
           cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+        assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
         if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
           MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
         AllToInit.push_back(Value);
@@ -1224,18 +1232,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
       else {
         CXXRecordDecl *BaseDecl =
           cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+        assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
          CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context);
-        if (!Ctor)
+        if (!Ctor) {
           Bases.push_back(Base);
-        else
-          MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+          continue;
+        }
+
+        ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+        if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0), 
+                                     Constructor->getLocation(), CtorArgs))
+          continue;
+        
+        MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
 
         CXXBaseOrMemberInitializer *Member =
-        new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
-                                      BaseDecl->getDefaultConstructor(Context),
-                                      SourceLocation(),
-                                      SourceLocation());
+          new (Context) CXXBaseOrMemberInitializer(Base->getType(),
+                                                   CtorArgs.takeAs<Expr>(),
+                                                   CtorArgs.size(), Ctor,
+                                                   SourceLocation(),
+                                                   SourceLocation());
         AllToInit.push_back(Member);
       }
     }
@@ -1268,7 +1284,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
       QualType FT = (*Field)->getType();
       if (const RecordType* RT = FT->getAs<RecordType>()) {
         CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RT->getDecl());
-        assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null");
+        assert(FieldRecDecl && "SetBaseOrMemberInitializers - BaseDecl null");
         if (CXXConstructorDecl *Ctor =
               FieldRecDecl->getDefaultConstructor(Context))
           MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
@@ -1281,13 +1297,22 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
     if (const RecordType* RT = FT->getAs<RecordType>()) {
       CXXConstructorDecl *Ctor =
         cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(Context);
-      if (!Ctor && !FT->isDependentType())
+      if (!Ctor && !FT->isDependentType()) {
         Fields.push_back(*Field);
+        continue;
+      }
+      
+      ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+      if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0), 
+                                  Constructor->getLocation(), CtorArgs))
+        continue;
+      
       CXXBaseOrMemberInitializer *Member =
-      new (Context) CXXBaseOrMemberInitializer((*Field), 0, 0,
-                                         Ctor,
-                                         SourceLocation(),
-                                         SourceLocation());
+        new (Context) CXXBaseOrMemberInitializer(*Field,CtorArgs.takeAs<Expr>(),
+                                                 CtorArgs.size(), Ctor,
+                                                 SourceLocation(),
+                                                 SourceLocation());
+
       AllToInit.push_back(Member);
       if (Ctor)
         MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
@@ -1327,10 +1352,10 @@ Sema::BuildBaseOrMemberInitializers(ASTContext &C,
                                  CXXBaseOrMemberInitializer **Initializers,
                                  unsigned NumInitializers
                                  ) {
-  llvm::SmallVector<CXXBaseSpecifier *, 4>Bases;
-  llvm::SmallVector<FieldDecl *, 4>Members;
+  llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
+  llvm::SmallVector<FieldDecl *, 4> Members;
 
-  setBaseOrMemberInitializers(Constructor,
+  SetBaseOrMemberInitializers(Constructor,
                               Initializers, NumInitializers, Bases, Members);
   for (unsigned int i = 0; i < Bases.size(); i++)
     Diag(Bases[i]->getSourceRange().getBegin(),
index 575283ed8b513b9fcaf384b4ed238ae0617ce33c..9c0f1ecf0c3b7d5450194aa63a96b577efe7a9df 100644 (file)
@@ -84,3 +84,27 @@ struct X1 {
 void test_X1() {
   X1<int> x1;
 }
+
+// PR5283
+namespace PR5283 {
+template<typename T> struct A {
+  A(T = 1); // expected-error 3 {{incompatible type initializing 'int', expected 'int *'}}
+};
+
+struct B : A<int*> { 
+  B();
+};
+B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct C : virtual A<int*> {
+  C();
+};
+C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct D {
+  D();
+  
+  A<int*> a;
+};
+D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+}