[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #8 from Younan Zhang  ---
Sorry for duplicate comments. Network issue :(
And thanks Patrik's explaination.

[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #7 from Younan Zhang  ---
(In reply to Patrick Palka from comment #4)
> (In reply to Younan Zhang from comment #2)
> > (In reply to Patrick Palka from comment #1)
> > > #1 is neither a non-template friend declaration with a requires-clause 
> > > nor a
> > > friend function template with a constraint that depends on a template
> > > parameter from an enclosing template, so it seems to me [temp.friend]/9
> > > doesn't apply here?
> > 
> > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to
> > template where `Us` depends on parameter from outter C?
> > ```cpp
> > template 
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template  requires (C && ...)
> friend auto factory(const Us&...);
> ```
> 
> so the friend doesn't have a constraint that depends on an outer template
> parameter (Ts)

Oh I see. I thought C was the template parameter, which should be a concept.

[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #6 from Younan Zhang  ---
(In reply to Patrick Palka from comment #4)
> (In reply to Younan Zhang from comment #2)
> > (In reply to Patrick Palka from comment #1)
> > > #1 is neither a non-template friend declaration with a requires-clause 
> > > nor a
> > > friend function template with a constraint that depends on a template
> > > parameter from an enclosing template, so it seems to me [temp.friend]/9
> > > doesn't apply here?
> > 
> > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to
> > template where `Us` depends on parameter from outter C?
> > ```cpp
> > template 
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template  requires (C && ...)
> friend auto factory(const Us&...);
> ```
> 
> so the friend doesn't have a constraint that depends on an outer template
> parameter (Ts)

Oh I see. I thought C was the template parameter, which should be a concept.

[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

Younan Zhang  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Younan Zhang  ---
(In reply to Patrick Palka from comment #4)
> (In reply to Younan Zhang from comment #2)
> > (In reply to Patrick Palka from comment #1)
> > > #1 is neither a non-template friend declaration with a requires-clause 
> > > nor a
> > > friend function template with a constraint that depends on a template
> > > parameter from an enclosing template, so it seems to me [temp.friend]/9
> > > doesn't apply here?
> > 
> > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to
> > template where `Us` depends on parameter from outter C?
> > ```cpp
> > template 
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template  requires (C && ...)
> friend auto factory(const Us&...);
> ```
> 
> so the friend doesn't have a constraint that depends on an outer template
> parameter (Ts)

Oh I see. I thought C was the template parameter, which should be a concept.

[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #3 from Younan Zhang  ---
(In reply to Younan Zhang from comment #2)
> (In reply to Patrick Palka from comment #1)
> > #1 is neither a non-template friend declaration with a requires-clause nor a
> > friend function template with a constraint that depends on a template
> > parameter from an enclosing template, so it seems to me [temp.friend]/9
> > doesn't apply here?
> 
> I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to
> template where `Us` depends on parameter from outter C?
> ```cpp
> template 
> friend auto factory(const C Us&...);`
> ```

typo: friend auto factory(const Us&...);

[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #2 from Younan Zhang  ---
(In reply to Patrick Palka from comment #1)
> #1 is neither a non-template friend declaration with a requires-clause nor a
> friend function template with a constraint that depends on a template
> parameter from an enclosing template, so it seems to me [temp.friend]/9
> doesn't apply here?

I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to
template where `Us` depends on parameter from outter C?
```cpp
template 
friend auto factory(const C Us&...);`
```

[Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?

2023-02-22 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

Bug ID: 108884
   Summary: [temp.friends]/9: Should constraint friends declared
in class scope differ with definition out of scope?
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zyn7109 at gmail dot com
  Target Milestone: ---

Clang implements deferred concept instantiation in
[D126907](https://reviews.llvm.org/D126907). As that patch suggests, according
to [temp.friend]/9, 

> A friend function template with a constraint that depends on a
> template parameter from an enclosing template shall be a definition.
> Such a constrained friend function or function template declaration
> does not declare the same function or function template as a
> declaration in any other scope.

That being said, such code should not compile as constrained friend declaration
(#1) doesn't declare the function defined out of class scope (#2).

(Example comes from https://github.com/clangd/clangd/issues/1511)

```cpp
// https://gcc.godbolt.org/z/sP9xdTqhe
template 
concept C = true;

template 
class Foo
{
private:
  Foo(const Ts&...) {};

public:
  friend auto factory(const C auto&...);  // #1
};

auto factory(const C auto&... ts)  // #2
{
  return Foo{ts...};
}

int main()
{
  factory(5);
}
```

Such code is rejected in Clang 16 onwards, showing that function defined at #2
is trying to access private constructor of `Foo`, but GCC still accepts this,
which implies GCC considers #1 and #2 are the same function. Is this a GCC
regression or I have missed something from the wording?

Note that if we swap #1 and #2, i.e.,
```cpp
// https://gcc.godbolt.org/z/WfG7vnxx8

template 
concept C = true;

template 
class Foo
{
private:
  Foo(const Ts&...) {}

public:
  friend auto factory(const C auto&... ts)
  {
return Foo{ts...};
  }
};

template 
auto factory(const C auto&... ts) -> Foo;

int main()
{
  factory(5);
}
```

then both GCC and Clang would accept it.

[Bug libstdc++/104465] std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)

2022-02-09 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465

--- Comment #6 from Younan Zhang  ---
(In reply to Jonathan Wakely from comment #4)
> But the reason that it accepts the argument is that it's an lvalue.
> 
> You tested std::ranges::viewable_range> but you
> should have tested std::ranges::viewable_range&>.


(In reply to Jonathan Wakely from comment #5)
> An lvalue vector has always been a viewable range. 

Yes you're right. `foo(v)` will return 1 now:

```cpp
template 
int foo(T) requires std::ranges::viewable_range { return 1; }
int foo(auto) { return 0; }
```

I also tested `auto(v) | std::views::reverse` and GCC rejects with:

```
...required for the satisfaction of 'viewable_range<_Range>':
note: no operand of the disjunction is satisfied...
```


(In reply to Jonathan Wakely from comment #5)
> That's just because Clang is broken and doesn't work with any libstdc++ views:
https://github.com/llvm/llvm-project/issues/44178

looks subtle ;)

Thanks for your detailed answer~

[Bug libstdc++/104465] std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)

2022-02-09 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465

--- Comment #1 from Younan Zhang  ---
* link typo for Clang 13 demo: https://gcc.godbolt.org/z/f7Eb53zb5

[Bug libstdc++/104465] New: std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)

2022-02-09 Thread zyn7109 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465

Bug ID: 104465
   Summary: std::vector should satisfy
std::ranges::viewable_range (P2415 for -c++2b)
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zyn7109 at gmail dot com
  Target Milestone: ---

Given the following code,

```cpp
#include 
#include 
#include 
#include 

int foo(std::ranges::viewable_range auto) { return 1; } // #1
int foo(auto) { return 0; }  // #2

int main() {
  const std::vector v {"1", "2", "3", "4"};
  std::cout << foo(v) << " ";
  for (auto vv: v | std::views::reverse) std::cout << vv << " ";   // #3
}
```

compiling with GCC 12.0.1 (20220208)
(https://wandbox.org/permlink/aPZzDSVF0wbtUQF8), the output is "0 4 3 2 1"
rather than "1 4 3 2 1" since the overload resolution selects #2 for `foo`.
However, as P2415 was merged into C++23
(https://github.com/cplusplus/papers/issues/1085), `std::vector`
is now a `viewable_range` and with Clang 15, "1 4 3 2 1" is the result.
(https://wandbox.org/permlink/8uzBa0Ot6Yj22Z0l).

It seems that P2415 is still not implemented for libstdc++ yet. However, GCC
accepts #3 since range was introduced from GCC 10.x (I'm not quite sure which
version) while considering
`std::ranges::viewable_range> == false`. As the
cppreference (https://en.cppreference.com/w/cpp/ranges/reverse_view) or C++20
draft suggests (24.7.1 [range.adaptor.object]/1,
https://timsong-cpp.github.io/cppwp/n4861/range.adaptors#range.adaptor.object-1),
the range adaptor `std::views::reverse` only takes `viewable_range` as
arguments. So it makes me confused and I wonder if I missed something.

Clang 13 rejects the above code (https://gcc.godbolt.org/z/xoKesEz7q), which is
as expected.