Issue |
132592
|
Summary |
[clang] Instantiation of concept makes invalid _expression_ valid.
|
Labels |
clang
|
Assignees |
|
Reporter |
SainoNamkho
|
Clang accepts or rejects the code depends on whether a related concept is instantiated before.
[Godbolt link](https://godbolt.org/z/4a5bq1efM)
```c++
#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:
```c++
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>()[]);
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs