mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 21:55:39 +08:00
Revert "[Clang] Preserve more sugars in constraint evaluation" (#163322)
Reverts llvm/llvm-project#162991 That patch breaks certain uses of VLAs when combined with constrained types. This is a pre-existing issue that occurs when concepts are instantiated with sugar. See also #102353 and related PRs. I tried to fix it on top of the status quo in #163167, but that approach turned out to be unfeasible, and our maintainer was clearly unhappy with it, hence this revert. Even after this patch, some VLA uses remain broken on trunk (see the example below), because our normalization patch depends on sugar to correctly compile libc++, due to a very subtle underlying bug. Still, this is the best attempt to mitigate the problem for now. We discussed this and agreed that the long-term solution is to remove the sugar dependencies from concepts, before the VLA issue is properly resolved through a larger refactoring. I'll add a related test (which passes with partially applied sugar) after this revert, since I don't have a reduced example yet.
This commit is contained in:
@@ -614,7 +614,8 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
|
||||
for (unsigned I = 0, MappedIndex = 0; I < Used.size(); I++) {
|
||||
TemplateArgument Arg;
|
||||
if (Used[I])
|
||||
Arg = CTAI.SugaredConverted[MappedIndex++];
|
||||
Arg = S.Context.getCanonicalTemplateArgument(
|
||||
CTAI.SugaredConverted[MappedIndex++]);
|
||||
if (I < SubstitutedOuterMost.size()) {
|
||||
SubstitutedOuterMost[I] = Arg;
|
||||
Offset = I + 1;
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace std_example {
|
||||
template<typename T> constexpr bool is_same_v<T, T> = true;
|
||||
|
||||
template<typename T, typename U> concept same_as = is_same_v<T, U>;
|
||||
// expected-note@-1 {{because 'is_same_v<int, typename T2::inner>' evaluated to false}}
|
||||
// expected-note@-1 {{because 'is_same_v<int, typename std_example::T2::inner>' evaluated to false}}
|
||||
|
||||
static_assert(C1<int>);
|
||||
static_assert(C1<int*>);
|
||||
@@ -160,7 +160,7 @@ namespace std_example {
|
||||
template<typename T> concept C2 =
|
||||
requires(T x) {
|
||||
{*x} -> same_as<typename T::inner>;
|
||||
// expected-note@-1{{because 'same_as<int, typename T2::inner>' evaluated to false}}
|
||||
// expected-note@-1{{because 'same_as<int, typename std_example::T2::inner>' evaluated to false}}
|
||||
// expected-note@-2{{because '*x' would be invalid: indirection requires pointer operand ('int' invalid)}}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ using r4i = X<void>::r4<int>; // expected-error{{constraints not satisfied for c
|
||||
|
||||
// C++ [expr.prim.req.nested] Examples
|
||||
namespace std_example {
|
||||
template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(decltype(+t)) == 1' (4 == 1) evaluated to false}}
|
||||
template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}}
|
||||
template<typename T> concept D =
|
||||
requires (T t) {
|
||||
requires C1<decltype (+t)>; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}}
|
||||
|
||||
@@ -95,8 +95,8 @@ concept OneOf = (is_same_v<T, Ts> || ...); // #OneOf
|
||||
// expected-note@#OneOf 3{{because 'is_same_v<int, char[1]>' evaluated to false}}
|
||||
// expected-note@#OneOf 3{{and 'is_same_v<int, char[2]>' evaluated to false}}
|
||||
// expected-note@#OneOf {{because 'is_same_v<decltype(nullptr), char>' evaluated to false}}
|
||||
// expected-note@#OneOf {{because 'is_same_v<decltype(nullptr), char>' evaluated to false}}
|
||||
// expected-note@#OneOf {{and 'is_same_v<decltype(nullptr), int>' evaluated to false}}
|
||||
// expected-note@#OneOf {{because 'is_same_v<std::nullptr_t, char>' evaluated to false}}
|
||||
// expected-note@#OneOf {{and 'is_same_v<std::nullptr_t, int>' evaluated to false}}
|
||||
// expected-note@#OneOf {{and 'is_same_v<decltype(nullptr), int>' evaluated to false}}
|
||||
|
||||
template<OneOf<char[1], char[2]> T, OneOf<int, long, char> U>
|
||||
|
||||
@@ -20,7 +20,7 @@ Buffer<double2> r4;
|
||||
// expected-error@+4 {{constraints not satisfied for class template 'Buffer'}}
|
||||
// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class Buffer}}
|
||||
// expected-note@*:* {{because 'Buffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(Buffer<int>)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(hlsl::Buffer<int>)' evaluated to false}}
|
||||
Buffer<Buffer<int> > r5;
|
||||
|
||||
struct s {
|
||||
@@ -66,7 +66,7 @@ Buffer<half[4]> r10;
|
||||
typedef vector<int, 8> int8;
|
||||
// expected-error@+3 {{constraints not satisfied for class template 'Buffer'}}
|
||||
// expected-note@*:* {{because 'int8' (aka 'vector<int, 8>') does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(int8)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(vector<int, 8>)' evaluated to false}}
|
||||
Buffer<int8> r11;
|
||||
|
||||
typedef int MyInt;
|
||||
@@ -91,7 +91,7 @@ Buffer<numbers> r15;
|
||||
|
||||
// expected-error@+3 {{constraints not satisfied for class template 'Buffer'}}
|
||||
// expected-note@*:* {{because 'double3' (aka 'vector<double, 3>') does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(double3)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(vector<double, 3>)' evaluated to false}}
|
||||
Buffer<double3> r16;
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ RWBuffer<double2> r4;
|
||||
// expected-error@+4 {{constraints not satisfied for class template 'RWBuffer'}}
|
||||
// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
|
||||
// expected-note@*:* {{because 'RWBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(hlsl::RWBuffer<int>)' evaluated to false}}
|
||||
RWBuffer<RWBuffer<int> > r5;
|
||||
|
||||
struct s {
|
||||
@@ -66,7 +66,7 @@ RWBuffer<half[4]> r10;
|
||||
typedef vector<int, 8> int8;
|
||||
// expected-error@+3 {{constraints not satisfied for class template 'RWBuffer'}}
|
||||
// expected-note@*:* {{because 'int8' (aka 'vector<int, 8>') does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(int8)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(vector<int, 8>)' evaluated to false}}
|
||||
RWBuffer<int8> r11;
|
||||
|
||||
typedef int MyInt;
|
||||
@@ -91,7 +91,7 @@ RWBuffer<numbers> r15;
|
||||
|
||||
// expected-error@+3 {{constraints not satisfied for class template 'RWBuffer'}}
|
||||
// expected-note@*:* {{because 'double3' (aka 'vector<double, 3>') does not satisfy '__is_typed_resource_element_compatible'}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(double3)' evaluated to false}}
|
||||
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(vector<double, 3>)' evaluated to false}}
|
||||
RWBuffer<double3> r16;
|
||||
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ struct my_range{
|
||||
void baz() {
|
||||
auto it = begin(rng); // #BEGIN_CALL
|
||||
// expected-error-re@#INF_REQ {{satisfaction of constraint {{.*}} depends on itself}}
|
||||
// expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<struct my_range>' requested here}}
|
||||
// expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin<struct my_range>' required here}}
|
||||
// expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<DirectRecursiveCheck::my_range>' requested here}}
|
||||
// expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}}
|
||||
// expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}}
|
||||
// expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}}
|
||||
// expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}}
|
||||
|
||||
@@ -833,13 +833,13 @@ struct Parent {
|
||||
static_assert(Parent<void>::TakesUnary<int, 0>::i == 0);
|
||||
// expected-error@+3{{constraints not satisfied for class template 'TakesUnary'}}
|
||||
// expected-note@#UNARY{{because 'decltype(0ULL)' (aka 'unsigned long long') does not satisfy 'C'}}
|
||||
// expected-note@#61777_C{{because 'sizeof(decltype(0ULL)) == 4' (8 == 4) evaluated to false}}
|
||||
// expected-note@#61777_C{{because 'sizeof(unsigned long long) == 4' (8 == 4) evaluated to false}}
|
||||
static_assert(Parent<void>::TakesUnary<int, 0uLL>::i == 0);
|
||||
|
||||
static_assert(Parent<int>::TakesBinary<int, 0>::i == 0);
|
||||
// expected-error@+3{{constraints not satisfied for class template 'TakesBinary'}}
|
||||
// expected-note@#BINARY{{because 'C2<decltype(0ULL), int>' evaluated to false}}
|
||||
// expected-note@#61777_C2{{because 'sizeof(decltype(0ULL)) == sizeof(int)' (8 == 4) evaluated to false}}
|
||||
// expected-note@#61777_C2{{because 'sizeof(unsigned long long) == sizeof(int)' (8 == 4) evaluated to false}}
|
||||
static_assert(Parent<int>::TakesBinary<int, 0ULL>::i == 0);
|
||||
}
|
||||
|
||||
@@ -1329,8 +1329,8 @@ static_assert(__cpp17_iterator<not_move_constructible>); \
|
||||
// expected-error {{static assertion failed}} \
|
||||
// expected-note {{because 'not_move_constructible' does not satisfy '__cpp17_iterator'}} \
|
||||
// expected-note@#__cpp17_copy_constructible {{because 'not_move_constructible' does not satisfy '__cpp17_copy_constructible'}} \
|
||||
// expected-note@#__cpp17_move_constructible {{because 'not_move_constructible' does not satisfy '__cpp17_move_constructible'}} \
|
||||
// expected-note@#is_move_constructible_v {{because 'is_move_constructible_v<not_move_constructible>' evaluated to false}}
|
||||
// expected-note@#__cpp17_move_constructible {{because 'parameter_mapping_regressions::case3::not_move_constructible' does not satisfy '__cpp17_move_constructible'}} \
|
||||
// expected-note@#is_move_constructible_v {{because 'is_move_constructible_v<parameter_mapping_regressions::case3::not_move_constructible>' evaluated to false}}
|
||||
}
|
||||
|
||||
namespace case4 {
|
||||
|
||||
Reference in New Issue
Block a user