summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaCXXCast.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp17
-rw-r--r--clang/lib/Sema/SemaOverload.cpp6
-rw-r--r--clang/test/SemaTemplate/instantiate-complete.cpp21
-rw-r--r--clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg1
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])
OpenPOWER on IntegriCloud