Skip to content

<type_traits>: Logical operator traits with non-bool_constant arguments emit truncation warnings #4845

@StephanTLavavej

Description

@StephanTLavavej
  • Repros with VS 2022 17.11 Preview 4.
  • Related to internal VSO-2170500 "C1XX's type trait optimization mishandles conjunction/disjunction with non-bool types".
    • Use /d1disableTypeTraitOptimization to work around that.
C:\Temp>type meow.cpp
#include <type_traits>
using namespace std;

template <typename Base, typename Derived>
void test_base_derived() {
    static_assert(is_base_of_v<Base, Derived>);
    using ValueType = Base::value_type;
    static_assert(is_same_v<const ValueType, decltype(Derived::type::value)>);
    static_assert(Base::value == Derived::type::value);
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-2170500 (C1XX type trait optimization)
    static_assert(is_same_v<const ValueType, decltype(Derived::value)>);
    static_assert(Base::value == Derived::value);
#endif // ^^^ no workaround ^^^
}

template <short N>
using SC = integral_constant<short, N>;
template <long N>
using LC = integral_constant<long, N>;

void test_conjunction() {
    // N4986 [meta.logical]/5:
    // The specialization conjunction<B1, ..., BN> has a public and unambiguous base that is either
    // - the first type Bi in the list true_type, B1, ..., BN for which bool(Bi::value) is false, or
    // - if there is no such Bi, the last type in the list.
    test_base_derived<LC<3>, conjunction<SC<2>, LC<3>>>();
    test_base_derived<LC<0>, conjunction<SC<4>, LC<0>>>();
    test_base_derived<SC<0>, conjunction<SC<0>, LC<5>>>();
    test_base_derived<SC<0>, conjunction<SC<0>, LC<0>>>();
}

void test_disjunction() {
    // N4986 [meta.logical]/10:
    // The specialization disjunction<B1, ..., BN> has a public and unambiguous base that is either
    // - the first type Bi in the list false_type, B1, ..., BN for which bool(Bi::value) is true, or
    // - if there is no such Bi, the last type in the list.
    test_base_derived<SC<6>, disjunction<SC<6>, LC<7>>>();
    test_base_derived<SC<8>, disjunction<SC<8>, LC<0>>>();
    test_base_derived<LC<9>, disjunction<SC<0>, LC<9>>>();
    test_base_derived<LC<0>, disjunction<SC<0>, LC<0>>>();
}

void test_negation() {
    // N4986 [meta.logical]/12:
    // The class template negation forms the logical negation of its template type argument.
    // The type negation<B> is a Cpp17UnaryTypeTrait with a base characteristic of bool_constant<!bool(B::value)>.
    test_base_derived<false_type, negation<SC<1729>>>();
    test_base_derived<true_type, negation<SC<0>>>();
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /c meow.cpp
meow.cpp
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\type_traits(47): warning C4305: 'specialization': truncation from 'const _Ty' to 'bool'
        with
        [
            _Ty=short
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\type_traits(47): note: the template instantiation context (the oldest one first) is
meow.cpp(26): note: see reference to function template instantiation 'void test_base_derived<std::integral_constant<long,3>,std::conjunction<std::integral_constant<short,2>,std::integral_constant<long,3>>>(void)' being compiled
meow.cpp(6): note: see reference to variable template 'const bool is_base_of_v<std::integral_constant<long,3>,std::conjunction<std::integral_constant<short,2>,std::integral_constant<long,3> > >' being compiled
meow.cpp(6): note: see reference to class template instantiation 'std::conjunction<std::integral_constant<short,2>,std::integral_constant<long,3>>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\type_traits(40): warning C4305: 'specialization': truncation from 'const _Ty' to 'bool'
        with
        [
            _Ty=long
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\type_traits(40): note: the template instantiation context (the oldest one first) is
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\type_traits(47): note: see reference to class template instantiation 'std::_Conjunction<true,_First,std::integral_constant<long,3>>' being compiled
        with
        [
            _First=std::integral_constant<short,2>
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\xtr1common(162): warning C4305: 'specialization': truncation from 'const _Ty' to 'bool'
        with
        [
            _Ty=short
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\xtr1common(162): note: the template instantiation context (the oldest one first) is
meow.cpp(37): note: see reference to function template instantiation 'void test_base_derived<std::integral_constant<short,6>,std::disjunction<std::integral_constant<short,6>,std::integral_constant<long,7>>>(void)' being compiled
meow.cpp(6): note: see reference to variable template 'const bool is_base_of_v<std::integral_constant<short,6>,std::disjunction<std::integral_constant<short,6>,std::integral_constant<long,7> > >' being compiled
meow.cpp(6): note: see reference to class template instantiation 'std::disjunction<std::integral_constant<short,6>,std::integral_constant<long,7>>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\xtr1common(155): warning C4305: 'specialization': truncation from 'const _Ty' to 'bool'
        with
        [
            _Ty=long
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\xtr1common(155): note: the template instantiation context (the oldest one first) is
meow.cpp(39): note: see reference to function template instantiation 'void test_base_derived<std::integral_constant<long,9>,std::disjunction<std::integral_constant<short,0>,std::integral_constant<long,9>>>(void)' being compiled
meow.cpp(6): note: see reference to variable template 'const bool is_base_of_v<std::integral_constant<long,9>,std::disjunction<std::integral_constant<short,0>,std::integral_constant<long,9> > >' being compiled
meow.cpp(6): note: see reference to class template instantiation 'std::disjunction<std::integral_constant<short,0>,std::integral_constant<long,9>>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.41.34021\include\xtr1common(162): note: see reference to class template instantiation 'std::_Disjunction<false,_First,std::integral_constant<long,9>>' being compiled
        with
        [
            _First=std::integral_constant<short,0>
        ]

Thanks to STL Discord user jerome1807 for the report. I have a fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions