Skip to content

<type_traits> std::is_trivially_copyable_v returns incorrect value in the presence of conditionally enabled constructors #62555

@alexkaratarakis

Description

@alexkaratarakis

Repro:

template <bool IS_CONST>
struct MyIterator
{
    constexpr MyIterator() noexcept = default;

    constexpr MyIterator(const MyIterator&) = default;
    constexpr MyIterator(MyIterator&&) noexcept = default;
    constexpr MyIterator& operator=(const MyIterator&) = default;
    constexpr MyIterator& operator=(MyIterator&&) noexcept = default;

    constexpr MyIterator(const MyIterator<false>&) noexcept
        requires IS_CONST
      : MyIterator{}
    {
    }

    // This works:
    //    template <bool IS_CONST2>
    //    constexpr MyIterator(const MyIterator<IS_CONST2>&) noexcept
    //        requires (IS_CONST and not IS_CONST2)
    //      : MyIterator{}
    //    {
    //    }
};

static_assert(std::is_trivially_copy_assignable_v<MyIterator<true>>);
static_assert(std::is_trivially_move_assignable_v<MyIterator<true>>);
static_assert(std::is_trivially_copy_constructible_v<MyIterator<true>>);
static_assert(std::is_trivially_move_constructible_v<MyIterator<true>>);
static_assert(std::is_standard_layout_v<MyIterator<true>>);
static_assert(std::is_trivially_destructible_v<MyIterator<true>>);
static_assert(std::is_trivially_copyable_v<MyIterator<true>>);

static_assert(std::is_trivially_copy_assignable_v<MyIterator<false>>);
static_assert(std::is_trivially_move_assignable_v<MyIterator<false>>);
static_assert(std::is_trivially_copy_constructible_v<MyIterator<false>>);
static_assert(std::is_trivially_move_constructible_v<MyIterator<false>>);
static_assert(std::is_standard_layout_v<MyIterator<false>>);
static_assert(std::is_trivially_destructible_v<MyIterator<false>>);
static_assert(std::is_trivially_copyable_v<MyIterator<false>>);  // FAILS with clang

The last line fails for clang, but is accepted by msvc/gcc.
Demo: https://godbolt.org/z/7sWPh5xYG

The alternative of using a template parameter that is constrained to be false instead of hard-coding false (see commented-out code) works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions