Skip to content

Commit

Permalink
[Clang] fold expression is considered atomic during constraints norma…
Browse files Browse the repository at this point in the history
…lization

`|| fold` is not disjunction; `&& fold` is not conjunction. Both are atomic per
current wording. See http://cplusplus.github.io/concepts-ts/ts-active.html#28.

D128750 accidentally tried to partially addresss this which is not desirable.
This patch reverts that part and associated test cases.
  • Loading branch information
Yuanfang Chen committed Oct 23, 2022
1 parent 0081671 commit c9447c6
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 29 deletions.
10 changes: 2 additions & 8 deletions clang/lib/Sema/SemaConcept.cpp
Expand Up @@ -1110,14 +1110,8 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {

// C++2a [temp.param]p4:
// [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
//
// Using the pattern suffices because the partial ordering rules guarantee
// the template paramaters are equivalent.
if (auto *FoldE = dyn_cast<const CXXFoldExpr>(E)) {
assert(FoldE->isRightFold() && FoldE->getOperator() == BO_LAnd);
assert(E->IgnoreParenImpCasts() == E);
E = FoldE->getPattern();
}
// Fold expression is considered atomic constraints per current wording.
// See http://cplusplus.github.io/concepts-ts/ts-active.html#28

if (LogicalBinOp BO = E) {
auto LHS = fromConstraintExpr(S, D, BO.getLHS());
Expand Down
29 changes: 8 additions & 21 deletions clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
Expand Up @@ -44,23 +44,8 @@ template<C T, E auto M, int W, A S,
typename... Z>
void foo(T, U<T, M, W, S, Z...>);

// check auto template parameter pack.
template<C T, auto M, int W, A S,
template<typename, auto, int, A, auto...> class U,
C auto... Z>
void foo2(T, U<T, M, W, S, Z...>) = delete;
template<C T, auto M, int W, A S,
template<typename, auto, int, A, auto...> class U,
D auto... Z>
void foo2(T, U<T, M, W, S, Z...>) = delete;
template<C T, auto M, int W, A S,
template<typename, auto, int, A, auto...> class U,
E auto... Z>
void foo2(T, U<T, M, W, S, Z...>);

void bar(S<int, 1, 1, A{}, int> s, S2<int, 1, 1, A{}, 0, 0u> s2) {
foo(0, s);
foo2(0, s2);
}

template<C auto... T> void bar2();
Expand Down Expand Up @@ -110,8 +95,9 @@ template<D T, C V> struct Y4<V, T>; // expected-error {{class template partial s
template<C auto T> struct W1;
template<D auto T> struct W1<T> {};

template<C auto... T> struct W2;
template<D auto... T> struct W2<T...> {};
// See http://cplusplus.github.io/concepts-ts/ts-active.html#28
// template<C auto... T> struct W2;
// template<D auto... T> struct W2<T...> {};

template<class T, class U>
concept C1 = C<T> && C<U>;
Expand All @@ -121,8 +107,9 @@ concept D1 = D<T> && C<U>;
template<C1<A> auto T> struct W3;
template<D1<A> auto T> struct W3<T> {};

template<C1<A> auto... T> struct W4;
template<D1<A> auto... T> struct W4<T...> {};
// See http://cplusplus.github.io/concepts-ts/ts-active.html#28
// template<C1<A> auto... T> struct W4;
// template<D1<A> auto... T> struct W4<T...> {};

// FIXME: enable once Clang support non-trivial auto on NTTP.
// template<C auto* T> struct W5;
Expand All @@ -133,9 +120,9 @@ template<D1<A> auto... T> struct W4<T...> {};
// template<D auto& T> struct W6<T> {};

struct W1<0> w1;
struct W2<0> w2;
// struct W2<0> w2;
struct W3<0> w3;
struct W4<0> w4;
// struct W4<0> w4;
// FIXME: enable once Clang support non-trivial auto on NTTP.
// struct W5<(int*)nullptr> w5;
// struct W6<w5> w6;
Expand Down

0 comments on commit c9447c6

Please sign in to comment.