forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PR45589: Properly decompose overloaded
&&
and ||
operators in
constraint expressions. We create overloaded `&&` and `||` operators to hold the possible unqualified lookup results (if any) when the operands are dependent. We could avoid building these in some cases (we will never use the stored lookup results, and it would be better to not store them or perform the lookups), but in the general case we will probably still need to handle overloaded operators even with that optimization.
- Loading branch information
Showing
4 changed files
with
98 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// RUN: %clang_cc1 -std=c++20 -verify %s | ||
// RUN: %clang_cc1 -std=c++20 -verify %s -DDEPENDENT_OR | ||
|
||
#ifdef DEPENDENT_OR | ||
// This causes the || below to be a CXXOperatorCallExpr not a BinaryOperator. | ||
struct A {}; bool operator||(A, A); | ||
#endif | ||
|
||
namespace PR45589 { | ||
template<typename T> struct X { static constexpr bool value = T::value; }; // expected-error {{cannot be used prior to '::'}} | ||
struct False { static constexpr bool value = false; }; | ||
struct True { static constexpr bool value = true; }; | ||
|
||
template<typename T> concept C = true; | ||
|
||
template<bool B, typename T> constexpr int test = 0; | ||
template<bool B, typename T> requires C<T> constexpr int test<B, T> = 1; | ||
template<bool B, typename T> requires (B && C<T>) || (X<T>::value && C<T>) constexpr int test<B, T> = 2; // expected-error {{non-constant expression}} expected-note {{subexpression}} expected-note {{instantiation of}} expected-note {{while substituting}} | ||
static_assert(test<true, False> == 2); | ||
static_assert(test<true, True> == 2); | ||
static_assert(test<true, char> == 2); // satisfaction of second term of || not considered | ||
static_assert(test<false, False> == 1); | ||
static_assert(test<false, True> == 2); // constraints are partially ordered | ||
// FIXME: These diagnostics are excessive. | ||
static_assert(test<false, char> == 1); // expected-note 2{{while}} expected-note 2{{during}} | ||
} |