public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
@ 2023-02-22 12:02 zyn7109 at gmail dot com
  2023-02-22 14:03 ` [Bug c++/108884] " ppalka at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 12:02 UTC (permalink / raw)
  To: 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 <typename>
concept C = true;

template <C... Ts>
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 <typename>
concept C = true;

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

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

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

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

then both GCC and Clang would accept it.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
@ 2023-02-22 14:03 ` ppalka at gcc dot gnu.org
  2023-02-22 14:11 ` zyn7109 at gmail dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-02-22 14:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ppalka at gcc dot gnu.org

--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
#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?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
  2023-02-22 14:03 ` [Bug c++/108884] " ppalka at gcc dot gnu.org
@ 2023-02-22 14:11 ` zyn7109 at gmail dot com
  2023-02-22 14:12 ` zyn7109 at gmail dot com
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:11 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #2 from Younan Zhang <zyn7109 at gmail dot com> ---
(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 <C... Us>
friend auto factory(const C Us&...);`
```

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
  2023-02-22 14:03 ` [Bug c++/108884] " ppalka at gcc dot gnu.org
  2023-02-22 14:11 ` zyn7109 at gmail dot com
@ 2023-02-22 14:12 ` zyn7109 at gmail dot com
  2023-02-22 14:24 ` ppalka at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #3 from Younan Zhang <zyn7109 at gmail dot com> ---
(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 <C... Us>
> friend auto factory(const C Us&...);`
> ```

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
                   ` (2 preceding siblings ...)
  2023-02-22 14:12 ` zyn7109 at gmail dot com
@ 2023-02-22 14:24 ` ppalka at gcc dot gnu.org
  2023-02-22 14:35 ` zyn7109 at gmail dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-02-22 14:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #4 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(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 <C... Us>
> friend auto factory(const C Us&...);`
> ```

And IIUC if we desugar the type-constraint C... we get

```cpp
template <class... Us> requires (C<Us> && ...)
friend auto factory(const Us&...);
```

so the friend doesn't have a constraint that depends on an outer template
parameter (Ts)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
                   ` (3 preceding siblings ...)
  2023-02-22 14:24 ` ppalka at gcc dot gnu.org
@ 2023-02-22 14:35 ` zyn7109 at gmail dot com
  2023-02-22 14:35 ` zyn7109 at gmail dot com
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

Younan Zhang <zyn7109 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #5 from Younan Zhang <zyn7109 at gmail dot com> ---
(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 <C... Us>
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template <class... Us> requires (C<Us> && ...)
> 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.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
                   ` (4 preceding siblings ...)
  2023-02-22 14:35 ` zyn7109 at gmail dot com
@ 2023-02-22 14:35 ` zyn7109 at gmail dot com
  2023-02-22 14:36 ` zyn7109 at gmail dot com
  2023-02-22 14:38 ` zyn7109 at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #6 from Younan Zhang <zyn7109 at gmail dot com> ---
(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 <C... Us>
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template <class... Us> requires (C<Us> && ...)
> 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.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
                   ` (5 preceding siblings ...)
  2023-02-22 14:35 ` zyn7109 at gmail dot com
@ 2023-02-22 14:36 ` zyn7109 at gmail dot com
  2023-02-22 14:38 ` zyn7109 at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #7 from Younan Zhang <zyn7109 at gmail dot com> ---
(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 <C... Us>
> > friend auto factory(const C Us&...);`
> > ```
> 
> And IIUC if we desugar the type-constraint C... we get
> 
> ```cpp
> template <class... Us> requires (C<Us> && ...)
> 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.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
  2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
                   ` (6 preceding siblings ...)
  2023-02-22 14:36 ` zyn7109 at gmail dot com
@ 2023-02-22 14:38 ` zyn7109 at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: zyn7109 at gmail dot com @ 2023-02-22 14:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884

--- Comment #8 from Younan Zhang <zyn7109 at gmail dot com> ---
Sorry for duplicate comments. Network issue :(
And thanks Patrik's explaination.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-02-22 14:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-22 12:02 [Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? zyn7109 at gmail dot com
2023-02-22 14:03 ` [Bug c++/108884] " ppalka at gcc dot gnu.org
2023-02-22 14:11 ` zyn7109 at gmail dot com
2023-02-22 14:12 ` zyn7109 at gmail dot com
2023-02-22 14:24 ` ppalka at gcc dot gnu.org
2023-02-22 14:35 ` zyn7109 at gmail dot com
2023-02-22 14:35 ` zyn7109 at gmail dot com
2023-02-22 14:36 ` zyn7109 at gmail dot com
2023-02-22 14:38 ` zyn7109 at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).