summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-01-28 22:02:36 +0000
committerJohn McCall <rjmccall@apple.com>2011-01-28 22:02:36 +0000
commit388ef5323481637af1f36f32a81523ee10294ff4 (patch)
tree210047ccca1540b9c4bd8ee0bceba05cf7dc076f /clang/lib/Sema/SemaExprCXX.cpp
parent6bcb81a7733e660d6523aa8c94b613251723ab32 (diff)
downloadbcm5719-llvm-388ef5323481637af1f36f32a81523ee10294ff4.tar.gz
bcm5719-llvm-388ef5323481637af1f36f32a81523ee10294ff4.zip
Fix some corner cases in the __is_base_of logic.
llvm-svn: 124505
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp47
1 files changed, 27 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 6ba18a54fd0..82e818fba05 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/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);
OpenPOWER on IntegriCloud