[cfe-commits] r102339 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/SemaTemplate/default-expr-arguments.cpp

Douglas Gregor dgregor at apple.com
Mon Apr 26 07:36:57 PDT 2010


Author: dgregor
Date: Mon Apr 26 09:36:57 2010
New Revision: 102339

URL: http://llvm.org/viewvc/llvm-project?rev=102339&view=rev
Log:
Ensure that we have completed a type before attempting initialization
on that type. Fixes several problems in Boost.Interprocess.

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=102339&r1=102338&r2=102339&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Apr 26 09:36:57 2010
@@ -2620,6 +2620,12 @@
   bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct ||
                         Kind.getKind() == InitializationKind::IK_Value ||
                         Kind.getKind() == InitializationKind::IK_Default);
+
+  // The type we're constructing needs to be complete.
+  if (S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
+    Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
+    return;
+  }
   
   // The type we're converting to is a class type. Enumerate its constructors
   // to see if one is suitable.
@@ -2806,48 +2812,51 @@
     CXXRecordDecl *DestRecordDecl
       = cast<CXXRecordDecl>(DestRecordType->getDecl());
     
-    DeclarationName ConstructorName
-      = S.Context.DeclarationNames.getCXXConstructorName(
+    // Try to complete the type we're converting to.
+    if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {    
+      DeclarationName ConstructorName
+        = S.Context.DeclarationNames.getCXXConstructorName(
                      S.Context.getCanonicalType(DestType).getUnqualifiedType());
-    DeclContext::lookup_iterator Con, ConEnd;
-    for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
-         Con != ConEnd; ++Con) {
-      NamedDecl *D = *Con;
-      DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
-      bool SuppressUserConversions = false;
-      
-      // Find the constructor (which may be a template).
-      CXXConstructorDecl *Constructor = 0;
-      FunctionTemplateDecl *ConstructorTmpl
-        = dyn_cast<FunctionTemplateDecl>(D);
-      if (ConstructorTmpl)
-        Constructor = cast<CXXConstructorDecl>(
+      DeclContext::lookup_iterator Con, ConEnd;
+      for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
+           Con != ConEnd; ++Con) {
+        NamedDecl *D = *Con;
+        DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+        bool SuppressUserConversions = false;
+        
+        // Find the constructor (which may be a template).
+        CXXConstructorDecl *Constructor = 0;
+        FunctionTemplateDecl *ConstructorTmpl
+          = dyn_cast<FunctionTemplateDecl>(D);
+        if (ConstructorTmpl)
+          Constructor = cast<CXXConstructorDecl>(
                                            ConstructorTmpl->getTemplatedDecl());
-      else {
-        Constructor = cast<CXXConstructorDecl>(D);
-        
-        // If we're performing copy initialization using a copy constructor, we 
-        // suppress user-defined conversions on the arguments.
-        // FIXME: Move constructors?
-        if (Kind.getKind() == InitializationKind::IK_Copy &&
-            Constructor->isCopyConstructor())
-          SuppressUserConversions = true;
+        else {
+          Constructor = cast<CXXConstructorDecl>(D);
+          
+          // If we're performing copy initialization using a copy constructor, 
+          // we suppress user-defined conversions on the arguments.
+          // FIXME: Move constructors?
+          if (Kind.getKind() == InitializationKind::IK_Copy &&
+              Constructor->isCopyConstructor())
+            SuppressUserConversions = true;
+          
+        }
         
-      }
-      
-      if (!Constructor->isInvalidDecl() &&
-          Constructor->isConvertingConstructor(AllowExplicit)) {
-        if (ConstructorTmpl)
-          S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                         /*ExplicitArgs*/ 0,
-                                         &Initializer, 1, CandidateSet,
-                                         SuppressUserConversions);
-        else
-          S.AddOverloadCandidate(Constructor, FoundDecl,
-                                 &Initializer, 1, CandidateSet,
-                                 SuppressUserConversions);
-      }
-    }    
+        if (!Constructor->isInvalidDecl() &&
+            Constructor->isConvertingConstructor(AllowExplicit)) {
+          if (ConstructorTmpl)
+            S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                           /*ExplicitArgs*/ 0,
+                                           &Initializer, 1, CandidateSet,
+                                           SuppressUserConversions);
+          else
+            S.AddOverloadCandidate(Constructor, FoundDecl,
+                                   &Initializer, 1, CandidateSet,
+                                   SuppressUserConversions);
+        }
+      }    
+    }
   }
 
   SourceLocation DeclLoc = Initializer->getLocStart();

Modified: cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp?rev=102339&r1=102338&r2=102339&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp (original)
+++ cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp Mon Apr 26 09:36:57 2010
@@ -188,3 +188,21 @@
 void f4_test(int i) {
   f4(i);
 }
+
+// Instantiate for initialization
+namespace InstForInit {
+  template<typename T>
+  struct Ptr {
+    typedef T* type;
+    Ptr(type);
+  };
+
+  template<typename T>
+  struct Holder {
+    Holder(int i, Ptr<T> ptr = 0);
+  };
+
+  void test_holder(int i) {
+    Holder<int> h(i);
+  }
+};





More information about the cfe-commits mailing list