Thanks to visit codestin.com
Credit goes to github.com

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions