Skip to content

[clang] Instantiation of concept makes invalid expression valid. #132592

Open
@SainoNamkho

Description

@SainoNamkho

Clang accepts or rejects the code depending on whether a related concept is instantiated before.

Godbolt link

#include <concepts>

struct Var {};

template<class T>
constexpr Var var;

struct A {};

template<class T> requires std::same_as<A, T>
constexpr auto var<T> = 1;

template<class T> requires std::same_as<T*, A*>
constexpr auto var<T> = 2;

template<class T>
concept C1 = var<T> == 1;

template<class T>
concept C2 = var<T> == 2;

template<class T>
concept C = C1<T> || C2<T>;

#ifdef __clang__
// static_assert(var<A> == 1 || var<A> == 2);               // clang reports error here
auto magic = C1<A>;
static_assert(var<A> == 1 && var<A> == 2 && var<A> == 42);  // clang doesn't report error here
#endif

#ifdef _MSC_VER
    static_assert(var<A> == 1);                 // msvc selects the first specializatioin
    static_assert(C1<A> && !C2<A> && C<A>);
#else
    static_assert(!C1<A> && !C2<A> && !C<A>);   // concept-ids of unsatisfied constraints are false
#endif

template<class T>
struct B;

template<C1 T>
struct B<T> : std::true_type {};

template<std::same_as<A> T>
struct B<T> : std::false_type {};

static_assert(!B<A>::value);    // msvc doesn't treat unsatisfication of C1 as sfinae

Minimal example:

template<class>
constexpr auto x = false;

template<class T> requires true
constexpr auto x<T> = true;

template<class T> requires true && true
constexpr auto x<T> = true;

template<class T>
concept X = x<T>;
// static_assert(x<void>);     //error
static_assert(!X<void>);
static_assert(x<void> && !x<void> && **x<void>()[]);

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"conceptsC++20 concepts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions