llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Aaron Advait Anish (skylarcs-the-limit) <details> <summary>Changes</summary> Part of #<!-- -->141911. This adds missing diagnostic notes explaining why std::is_integral fails. --- Full diff: https://github.com/llvm/llvm-project/pull/235416.diff 5 Files Affected: - (modified) clang/include/clang/Basic/BuiltinTraits.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6) - (modified) clang/lib/Sema/SemaTypeTraits.cpp (+38) - (modified) clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp (+47) - (modified) clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp (+56) ``````````diff diff --git a/clang/include/clang/Basic/BuiltinTraits.td b/clang/include/clang/Basic/BuiltinTraits.td index f80234dd21e145..a00ad3a24e5402 100644 --- a/clang/include/clang/Basic/BuiltinTraits.td +++ b/clang/include/clang/Basic/BuiltinTraits.td @@ -494,6 +494,7 @@ def IsFloatingPoint : UnaryTrait { def IsIntegral : UnaryTrait { let Spelling = "__is_integral"; + let StdName = "is_integral"; } def IsCompleteType : UnaryTrait { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dcb5732c3c19e7..0890bd0ad13461 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1855,6 +1855,7 @@ def note_unsatisfied_trait "%TriviallyRelocatable{trivially relocatable}|" "%TriviallyCopyable{trivially copyable}|" "%Empty{empty}|" + "%Integral{an integral type}|" "%StandardLayout{standard-layout}|" "%Aggregate{aggregate}|" "%Final{final}|" @@ -1908,6 +1909,11 @@ def note_unsatisfied_trait_reason "%NotClassOrUnion{is not a class or union type}|" "%NotMarkedFinal{is not marked 'final'}|" "%PointerType{is a pointer type}|" + "%FloatingPointType{is a floating-point type}|" + "%EnumType{is an enum type}|" + "%VoidType{is void}|" + "%ClassType{is a class type}|" + "%MemberPointerType{is a member pointer type}|" "%ArrayType{is an array type}|" "%UnionType{is a union type}|" "%NotStructOrClass{is not a struct or class type}|" diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index cb30ff9fd02da9..0a0e37ac0e0a50 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -2406,6 +2406,41 @@ static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, QualType T) { } } +static void DiagnoseNonIntegralReason(Sema &S, SourceLocation Loc, QualType T) { + S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Integral; + if (T->isFloatingType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::FloatingPointType; + } else if (T->isEnumeralType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::EnumType; + } else if (T->isPointerType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::PointerType; + } else if (T->isReferenceType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::Ref; + } else if (T->isArrayType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::ArrayType; + } else if (T->isUnionType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::UnionType; + } else if (T->isFunctionType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::FunctionType; + } else if (T->isVoidType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::VoidType; + } else if (T->isStructureOrClassType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::ClassType; + } else if (T->isMemberPointerType()) { + S.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::MemberPointerType; + } +} + static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D) { if (!D || D->isInvalidDecl()) @@ -2773,6 +2808,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) { case UTT_IsEmpty: DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]); break; + case UTT_IsIntegral: + DiagnoseNonIntegralReason(*this, E->getBeginLoc(), Args[0]); + break; case UTT_IsStandardLayout: DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]); break; diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp index 8a9f3bc400d206..2b301d02f496dd 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp @@ -73,6 +73,13 @@ struct is_abstract { template <typename T> constexpr bool is_abstract_v = __is_abstract(T); +template <typename T> +struct is_integral { + static constexpr bool value = __is_integral(T); +}; +template <typename T> +constexpr bool is_integral_v = __is_integral(T); + #endif #ifdef STD2 @@ -167,6 +174,15 @@ using is_abstract = __details_is_abstract<T>; template <typename T> constexpr bool is_abstract_v = __is_abstract(T); +template <typename T> +struct __details_is_integral { + static constexpr bool value = __is_integral(T); +}; +template <typename T> +using is_integral = __details_is_integral<T>; +template <typename T> +constexpr bool is_integral_v = __is_integral(T); + #endif @@ -252,6 +268,13 @@ using is_abstract = __details_is_abstract<T>; template <typename T> constexpr bool is_abstract_v = is_abstract<T>::value; +template <typename T> +struct __details_is_integral : bool_constant<__is_integral(T)> {}; +template <typename T> +using is_integral = __details_is_integral<T>; +template <typename T> +constexpr bool is_integral_v = is_integral<T>::value; + #endif } @@ -590,4 +613,28 @@ void test() { // expected-note@#concept10 {{'void' is not aggregate}} \ // expected-note@#concept10 {{because it is a cv void type}} } + static_assert(std::is_integral<double>::value); + // expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_integral<double>::value'}} \ + // expected-note@-1 {{'double' is not an integral type}} \ + // expected-note@-1 {{because it is a floating-point type}} + static_assert(std::is_integral_v<double>); + // expected-error@-1 {{static assertion failed due to requirement 'std::is_integral_v<double>'}} \ + // expected-note@-1 {{'double' is not an integral type}} \ + // expected-note@-1 {{because it is a floating-point type}} + + static_assert(std::is_integral_v<int*>); + // expected-error@-1 {{static assertion failed due to requirement 'std::is_integral_v<int *>'}} \ + // expected-note@-1 {{'int *' is not an integral type}} \ + // expected-note@-1 {{because it is a pointer type}} + + static_assert(std::is_integral_v<int&>); + // expected-error@-1 {{static assertion failed due to requirement 'std::is_integral_v<int &>'}} \ + // expected-note@-1 {{'int &' is not an integral type}} \ + // expected-note@-1 {{because it is a reference type}} + + enum E {}; + static_assert(std::is_integral_v<E>); + // expected-error@-1 {{static assertion failed due to requirement 'std::is_integral_v<concepts::E>'}} \ + // expected-note@-1 {{'concepts::E' is not an integral type}} \ + // expected-note@-1 {{because it is an enum type}} } diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp index 3bde5b06a3aba4..a4f42f5530a5b2 100644 --- a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp +++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp @@ -892,3 +892,59 @@ static_assert(__is_abstract(U)); // expected-note@-1 {{because it is not a struct or class type}} } + +namespace is_integral_tests { + static_assert(__is_integral(double)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(double)'}} \ + // expected-note@-1 {{'double' is not an integral type}} \ + // expected-note@-1 {{because it is a floating-point type}} + + static_assert(__is_integral(int*)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(int *)'}} \ + // expected-note@-1 {{'int *' is not an integral type}} \ + // expected-note@-1 {{because it is a pointer type}} + + static_assert(__is_integral(int&)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(int &)'}} \ + // expected-note@-1 {{'int &' is not an integral type}} \ + // expected-note@-1 {{because it is a reference type}} + + enum E {}; + static_assert(__is_integral(E)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(is_integral_tests::E)'}} \ + // expected-note@-1 {{'E' is not an integral type}} \ + // expected-note@-1 {{because it is an enum type}} + + static_assert(__is_integral(int[3])); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(int[3])'}} \ + // expected-note@-1 {{'int[3]' is not an integral type}} \ + // expected-note@-1 {{because it is an array type}} + + union U {}; + static_assert(__is_integral(U)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(is_integral_tests::U)'}} \ + // expected-note@-1 {{'U' is not an integral type}} \ + // expected-note@-1 {{because it is a union type}} + + struct S {}; + static_assert(__is_integral(S)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(is_integral_tests::S)'}} \ + // expected-note@-1 {{'S' is not an integral type}} \ + // expected-note@-1 {{because it is a class type}} + + static_assert(__is_integral(int S::*)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(int is_integral_tests::S::*)'}} \ + // expected-note@-1 {{'int S::*' is not an integral type}} \ + // expected-note@-1 {{because it is a member pointer type}} + + using F = int(char); + static_assert(__is_integral(F)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(int (char))'}} \ + // expected-note@-1 {{'F' (aka 'int (char)') is not an integral type}} \ + // expected-note@-1 {{because it is a function type}} + + static_assert(__is_integral(void)); + // expected-error@-1 {{static assertion failed due to requirement '__is_integral(void)'}} \ + // expected-note@-1 {{'void' is not an integral type}} \ + // expected-note@-1 {{because it is void}} +} `````````` </details> https://github.com/llvm/llvm-project/pull/235416 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
