diff options
-rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-complete.cpp | 21 | ||||
-rw-r--r-- | clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg | 1 |
6 files changed, 40 insertions, 11 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 4c81cb18de7..c4de6be9eb2 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3651,7 +3651,8 @@ public: Ref_Compatible }; - ReferenceCompareResult CompareReferenceRelationship(QualType T1, QualType T2, + ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, + QualType T1, QualType T2, bool& DerivedToBase); bool CheckReferenceInit(Expr *&simpleInit_or_initList, QualType declType, diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 8bb334855d0..76faddaa038 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -527,7 +527,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, // this is the only cast possibility, so we issue an error if we fail now. // FIXME: Should allow casting away constness if CStyle. bool DerivedToBase; - if (Self.CompareReferenceRelationship(SrcExpr->getType(), R->getPointeeType(), + if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(), + SrcExpr->getType(), R->getPointeeType(), DerivedToBase) < Sema::Ref_Compatible_With_Added_Qualification) { msg = diag::err_bad_lvalue_to_rvalue_cast; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 5b101247dad..b8977cfa142 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3604,14 +3604,15 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, /// type, and the first type (T1) is the pointee type of the reference /// type being initialized. Sema::ReferenceCompareResult -Sema::CompareReferenceRelationship(QualType T1, QualType T2, +Sema::CompareReferenceRelationship(SourceLocation Loc, + QualType OrigT1, QualType OrigT2, bool& DerivedToBase) { - assert(!T1->isReferenceType() && + assert(!OrigT1->isReferenceType() && "T1 must be the pointee type of the reference type"); - assert(!T2->isReferenceType() && "T2 cannot be a reference type"); + assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type"); - T1 = Context.getCanonicalType(T1); - T2 = Context.getCanonicalType(T2); + QualType T1 = Context.getCanonicalType(OrigT1); + QualType T2 = Context.getCanonicalType(OrigT2); QualType UnqualT1 = T1.getUnqualifiedType(); QualType UnqualT2 = T2.getUnqualifiedType(); @@ -3621,7 +3622,9 @@ Sema::CompareReferenceRelationship(QualType T1, QualType T2, // T1 is a base class of T2. if (UnqualT1 == UnqualT2) DerivedToBase = false; - else if (IsDerivedFrom(UnqualT2, UnqualT1)) + else if (!RequireCompleteType(Loc, OrigT1, PDiag()) && + !RequireCompleteType(Loc, OrigT2, PDiag()) && + IsDerivedFrom(UnqualT2, UnqualT1)) DerivedToBase = true; else return Ref_Incompatible; @@ -3697,7 +3700,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, Expr::isLvalueResult InitLvalue = ForceRValue ? Expr::LV_InvalidExpression : Init->isLvalue(Context); ReferenceCompareResult RefRelationship - = CompareReferenceRelationship(T1, T2, DerivedToBase); + = CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase); // Most paths end in a failed conversion. if (ICS) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index d2bdfb8e2cc..24c3ae391b5 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1387,8 +1387,10 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion( bool AllowExplicit, bool ForceRValue, bool UserCast) { if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) { - if (CXXRecordDecl *ToRecordDecl - = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) { + if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) { + // We're not going to find any constructors. + } else if (CXXRecordDecl *ToRecordDecl + = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) { // C++ [over.match.ctor]p1: // When objects of class type are direct-initialized (8.5), or // copy-initialized from an expression of the same or a diff --git a/clang/test/SemaTemplate/instantiate-complete.cpp b/clang/test/SemaTemplate/instantiate-complete.cpp index babc55217a9..507894a2ff6 100644 --- a/clang/test/SemaTemplate/instantiate-complete.cpp +++ b/clang/test/SemaTemplate/instantiate-complete.cpp @@ -45,3 +45,24 @@ void test_memptr(X<long> *p1, long X<long>::*pm1, (void)(p1->*pm1); (void)((p2->*pm2)(0)); } + +// Reference binding to a base +template<typename T> +struct X1 { }; + +template<typename T> +struct X2 : public T { }; + +void refbind_base(X2<X1<int> > &x2) { + X1<int> &x1 = x2; +} + +// Enumerate constructors for user-defined conversion. +template<typename T> +struct X3 { + X3(T); +}; + +void enum_constructors(X1<float> &x1) { + X3<X1<float> > x3 = x1; +} diff --git a/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg b/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg index 69f010ef335..8375f0920d3 100644 --- a/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg +++ b/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg @@ -16,6 +16,7 @@ config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, pattern='^(.*\\.h|[^.]*)$', extra_cxx_args=['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', + '-Wno-sign-compare', '-I%s/include' % root.llvm_src_root, '-I%s/include' % root.llvm_obj_root]) |