diff options
author | John McCall <rjmccall@apple.com> | 2011-01-28 22:02:36 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-01-28 22:02:36 +0000 |
commit | d89d30fdd9e3061fb100fb8f976aab5c6cf2c901 (patch) | |
tree | c6562af468641c9e8811d71eabe195035eb141b8 /lib/Sema/SemaExprCXX.cpp | |
parent | 21a7dfc48b6323178671a206c6bacda83c9ecd32 (diff) |
Fix some corner cases in the __is_base_of logic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124505 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 6ba18a54fd..82e818fba0 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2487,17 +2487,36 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, "Cannot evaluate traits for dependent types."); switch(BTT) { - case BTT_IsBaseOf: + case BTT_IsBaseOf: { // C++0x [meta.rel]p2 - // Base is a base class of Derived without regard to cv-qualifiers or + // Base is a base class of Derived without regard to cv-qualifiers or // Base and Derived are not unions and name the same class type without // regard to cv-qualifiers. - if (Self.IsDerivedFrom(RhsT, LhsT) || - (!LhsT->isUnionType() && !RhsT->isUnionType() - && LhsT->getAsCXXRecordDecl() == RhsT->getAsCXXRecordDecl())) - return true; - return false; + const RecordType *lhsRecord = LhsT->getAs<RecordType>(); + if (!lhsRecord) return false; + + const RecordType *rhsRecord = RhsT->getAs<RecordType>(); + if (!rhsRecord) return false; + + assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) + == (lhsRecord == rhsRecord)); + + if (lhsRecord == rhsRecord) + return !lhsRecord->getDecl()->isUnion(); + + // C++0x [meta.rel]p2: + // If Base and Derived are class types and are different types + // (ignoring possible cv-qualifiers) then Derived shall be a + // complete type. + if (Self.RequireCompleteType(KeyLoc, RhsT, + diag::err_incomplete_type_used_in_type_trait_expr)) + return false; + + return cast<CXXRecordDecl>(rhsRecord->getDecl()) + ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl())); + } + case BTT_TypeCompatible: return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(), RhsT.getUnqualifiedType()); @@ -2560,19 +2579,7 @@ ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT, QualType LhsT = LhsTSInfo->getType(); QualType RhsT = RhsTSInfo->getType(); - if (BTT == BTT_IsBaseOf) { - // C++0x [meta.rel]p2 - // If Base and Derived are class types and are different types - // (ignoring possible cv-qualifiers) then Derived shall be a complete - // type. [] - CXXRecordDecl *LhsDecl = LhsT->getAsCXXRecordDecl(); - CXXRecordDecl *RhsDecl = RhsT->getAsCXXRecordDecl(); - if (!LhsT->isDependentType() && !RhsT->isDependentType() && - LhsDecl && RhsDecl && LhsT != RhsT && - RequireCompleteType(KWLoc, RhsT, - diag::err_incomplete_type_used_in_type_trait_expr)) - return ExprError(); - } else if (BTT == BTT_TypeCompatible) { + if (BTT == BTT_TypeCompatible) { if (getLangOptions().CPlusPlus) { Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus) << SourceRange(KWLoc, RParen); |