aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-05 13:06:35 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-05 13:06:35 +0000
commit393896f49d5248435cf203cf1de60a86dc507c44 (patch)
tree2d1266a6f4ce90085c4b8104f62752dbca8bfffb /lib/Sema
parentb13c87f0c9705d91d5a3e134be9934c9ad531071 (diff)
Fixed two places where we needed to force completion of a type
(without complaining if it fails) to get proper semantics: reference binding with a derived-to-base conversion and the enumeration of constructors for user-defined conversions. There are probably more cases to fix, but my prior attempt at statically ensuring that complete-type checking always happens failed. Perhaps I'll try again. With this change, Clang can parse include/llvm/*.h! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86129 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaCXXCast.cpp3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp17
-rw-r--r--lib/Sema/SemaOverload.cpp6
4 files changed, 18 insertions, 11 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 4c81cb18de..c4de6be9eb 100644
--- a/lib/Sema/Sema.h
+++ b/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/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 8bb334855d..76faddaa03 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/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/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 5b101247da..b8977cfa14 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/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/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index d2bdfb8e2c..24c3ae391b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/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