-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Instantiation of concept makes invalid expression valid. #132592
Labels
Comments
To make it look weirder: 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> && !X<void>); // error
static_assert(!X<void> && x<void>); // compiles |
@llvm/issue-subscribers-clang-frontend Author: None (SainoNamkho)
Clang accepts or rejects the code depending on whether a related concept is instantiated before.
#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>()[]); |
clang is the only one that accepts the second one from the simplified example: https://godbolt.org/z/KGvrq3oxo and I don't think it should. CC @cor3ntin how does this fare w/ your latest PR? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Clang accepts or rejects the code depending on whether a related concept is instantiated before.
Godbolt link
Minimal example:
The text was updated successfully, but these errors were encountered: