aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-26 14:36:57 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-26 14:36:57 +0000
commit087fb7d0b5e08f34b2e28a09c376f66449f30886 (patch)
tree54f8b59e514067f9c5260f527a9daa207ebb1f56 /lib/Sema/SemaInit.cpp
parentb19f0ac4b68a60b88696dab1794cce33f273425f (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.cpp87
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();