diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-26 14:36:57 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-26 14:36:57 +0000 |
commit | 087fb7d0b5e08f34b2e28a09c376f66449f30886 (patch) | |
tree | 54f8b59e514067f9c5260f527a9daa207ebb1f56 /lib/Sema/SemaInit.cpp | |
parent | b19f0ac4b68a60b88696dab1794cce33f273425f (diff) |
Ensure that we have completed a type before attempting initialization
on that type. Fixes several problems in Boost.Interprocess.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102339 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 87 |
1 files changed, 48 insertions, 39 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index c413e67f04..ccd6d5f284 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2620,6 +2620,12 @@ static void TryConstructorInitialization(Sema &S, 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 @@ static void TryUserDefinedConversion(Sema &S, 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>( - 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; + 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; - } - - if (!Constructor->isInvalidDecl() && - Constructor->isConvertingConstructor(AllowExplicit)) { + // Find the constructor (which may be a template). + CXXConstructorDecl *Constructor = 0; + FunctionTemplateDecl *ConstructorTmpl + = dyn_cast<FunctionTemplateDecl>(D); if (ConstructorTmpl) - S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, - /*ExplicitArgs*/ 0, - &Initializer, 1, CandidateSet, - SuppressUserConversions); - else - S.AddOverloadCandidate(Constructor, FoundDecl, - &Initializer, 1, CandidateSet, - SuppressUserConversions); - } - } + 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; + + } + + 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(); |