diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-11-16 06:58:51 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-11-16 06:58:51 +0000 |
commit | 213bea336161eb06e94b8c02d2a9ab4869c8f983 (patch) | |
tree | 4cf92b9f02e38399af94ade2e82f03f86223338f /clang/lib/Sema/SemaExprCXX.cpp | |
parent | 2ac0c270017fb1c2fa1a894b9e2f96b96dca3423 (diff) | |
download | bcm5719-llvm-213bea336161eb06e94b8c02d2a9ab4869c8f983.tar.gz bcm5719-llvm-213bea336161eb06e94b8c02d2a9ab4869c8f983.zip |
[Sema] Implement several unary type traits more accurately
is_empty, is_polymorphic, and is_abstract didn't handle incomplete types
correctly. Only non-union class types must be complete for these
traits.
is_final and is_sealed don't care about the particular spelling of the
FinalAttr.
is_interface_class should always return false regardless of its input.
The type trait can only be satisfied in a mode we do not support (/CLR).
llvm-svn: 253184
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4b7db59444b..da34791395b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3550,27 +3550,43 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsVolatile: case UTT_IsSigned: case UTT_IsUnsigned: + + // This type trait always returns false, checking the type is moot. + case UTT_IsInterfaceClass: + return true; + + // C++14 [meta.unary.prop]: + // If T is a non-union class type, T shall be a complete type. + case UTT_IsEmpty: + case UTT_IsPolymorphic: + case UTT_IsAbstract: + if (const auto *RD = ArgTy->getAsCXXRecordDecl()) + if (!RD->isUnion()) + return !S.RequireCompleteType( + Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); + return true; + + // C++14 [meta.unary.prop]: + // If T is a class type, T shall be a complete type. + case UTT_IsFinal: + case UTT_IsSealed: + if (ArgTy->getAsCXXRecordDecl()) + return !S.RequireCompleteType( + Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); return true; - // C++0x [meta.unary.prop] Table 49 requires the following traits to be - // applied to a complete type. + // C++0x [meta.unary.prop] Table 49 requires the following traits to be + // applied to a complete type. case UTT_IsTrivial: case UTT_IsTriviallyCopyable: case UTT_IsStandardLayout: case UTT_IsPOD: case UTT_IsLiteral: - case UTT_IsEmpty: - case UTT_IsPolymorphic: - case UTT_IsAbstract: - case UTT_IsInterfaceClass: + case UTT_IsDestructible: case UTT_IsNothrowDestructible: // Fall-through - // These traits require a complete type. - case UTT_IsFinal: - case UTT_IsSealed: - // These trait expressions are designed to help implement predicates in // [meta.unary.prop] despite not being named the same. They are specified // by both GCC and the Embarcadero C++ compiler, and require the complete @@ -3729,24 +3745,21 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return false; case UTT_IsPolymorphic: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->isPolymorphic(); + return !RD->isUnion() && RD->isPolymorphic(); return false; case UTT_IsAbstract: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->isAbstract(); + return !RD->isUnion() && RD->isAbstract(); return false; + // __is_interface_class only returns true when CL is invoked in /CLR mode and + // even then only when it is used with the 'interface struct ...' syntax + // Clang doesn't support /CLR which makes this type trait moot. case UTT_IsInterfaceClass: - if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->isInterface(); return false; case UTT_IsFinal: - if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->hasAttr<FinalAttr>(); - return false; case UTT_IsSealed: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - if (FinalAttr *FA = RD->getAttr<FinalAttr>()) - return FA->isSpelledAsSealed(); + return RD->hasAttr<FinalAttr>(); return false; case UTT_IsSigned: return T->isSignedIntegerType(); |