public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/111608] New: Cannot declare partial specialization after full specialization
@ 2023-09-27  8:22 raplonu.jb at gmail dot com
  2023-09-27  8:54 ` [Bug c++/111608] " rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: raplonu.jb at gmail dot com @ 2023-09-27  8:22 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 111608
           Summary: Cannot declare partial specialization after full
                    specialization
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: raplonu.jb at gmail dot com
  Target Milestone: ---

The following code fails to compile with GCC 13.2 and under.

// primary template
template<typename T>
struct X {
    void f();
};

// definition of full template specialization before partial template
specialization
template<>
void X<int*>::f() {}

// partial template specialization declaration
template<typename T>
struct X<T*> {
    void f();
};

int main() {
    X<int*>{}.f();
}

gcc give the following message:

error: partial specialization of 'struct X<T*>' after instantiation of 'struct
X<int*>

which seems incorrect since their have different levels of specialization.

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

* [Bug c++/111608] Cannot declare partial specialization after full specialization
  2023-09-27  8:22 [Bug c++/111608] New: Cannot declare partial specialization after full specialization raplonu.jb at gmail dot com
@ 2023-09-27  8:54 ` rguenth at gcc dot gnu.org
  2023-09-27 12:05 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-09-27  8:54 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |13.2.0, 14.0, 7.5.0
           Keywords|                            |rejects-valid
   Last reconfirmed|                            |2023-09-27
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
clang accepts this.  Note you can use -fpermissive to demote the error to a
warning.

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

* [Bug c++/111608] Cannot declare partial specialization after full specialization
  2023-09-27  8:22 [Bug c++/111608] New: Cannot declare partial specialization after full specialization raplonu.jb at gmail dot com
  2023-09-27  8:54 ` [Bug c++/111608] " rguenth at gcc dot gnu.org
@ 2023-09-27 12:05 ` redi at gcc dot gnu.org
  2023-09-27 12:09 ` redi at gcc dot gnu.org
  2023-09-29  1:16 ` raplonu.jb at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-09-27 12:05 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
EDG rejects this too:

"spec.cc", line 13: error: this partial specialization would have been used to
          instantiate class "X<int *>"
  struct X<T*> {
         ^

1 error detected in the compilation of "spec.cc".

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

* [Bug c++/111608] Cannot declare partial specialization after full specialization
  2023-09-27  8:22 [Bug c++/111608] New: Cannot declare partial specialization after full specialization raplonu.jb at gmail dot com
  2023-09-27  8:54 ` [Bug c++/111608] " rguenth at gcc dot gnu.org
  2023-09-27 12:05 ` redi at gcc dot gnu.org
@ 2023-09-27 12:09 ` redi at gcc dot gnu.org
  2023-09-29  1:16 ` raplonu.jb at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-09-27 12:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Julien Bernard from comment #0)
> which seems incorrect since their have different levels of specialization.

But they're not the same thing. The first one is a specialization of the member
function, and defining that triggers the implicit instantiation of the
enclosing class template. That uses the primary template, but it would have
used the partial specialization of X<T*> if that had been seen already.

I suspect this is covered by [temp.point] p7:

"If two different points of instantiation give a template specialization
different meanings according to the one-definition rule (6.3), the program is
ill-formed, no diagnostic required."

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

* [Bug c++/111608] Cannot declare partial specialization after full specialization
  2023-09-27  8:22 [Bug c++/111608] New: Cannot declare partial specialization after full specialization raplonu.jb at gmail dot com
                   ` (2 preceding siblings ...)
  2023-09-27 12:09 ` redi at gcc dot gnu.org
@ 2023-09-29  1:16 ` raplonu.jb at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: raplonu.jb at gmail dot com @ 2023-09-29  1:16 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Julien Bernard <raplonu.jb at gmail dot com> ---
(In reply to Jonathan Wakely from comment #3)

I wasn't sure how to describe this issue, so my last sentence was probably
incorrect.

> I suspect this is covered by [temp.point] p7:
> 
> "If two different points of instantiation give a template specialization
> different meanings according to the one-definition rule (6.3), the program
> is ill-formed, no diagnostic required."

If I take this example:

// 1. primary template
template<typename T>
struct X {
    int f() { return 1; }
};

// 2. partial template specialization 
template<typename T>
struct X<T*> {
    int f() {return 2; }
};

// 3. full template specialization
template<>
struct X<int*> {
    int f() { return 3; }
};

This program is well formed. In addition, the above 3. full template
specialization is equivalent to the following 4. implicit instantiation in the
sense they produce the same program (please, correct me if I'm wrong):

// 4. implicit instantiation
template<>
int X<int*>::f() { return 3; }

If I move 3. between 1. and 2., it still compiles but won't when 4. is between
1. and 2.

Here is a live demo with gcc, clang and msvc as a simple point of comparison.

https://godbolt.org/z/36aceTTb5

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

end of thread, other threads:[~2023-09-29  1:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-27  8:22 [Bug c++/111608] New: Cannot declare partial specialization after full specialization raplonu.jb at gmail dot com
2023-09-27  8:54 ` [Bug c++/111608] " rguenth at gcc dot gnu.org
2023-09-27 12:05 ` redi at gcc dot gnu.org
2023-09-27 12:09 ` redi at gcc dot gnu.org
2023-09-29  1:16 ` raplonu.jb 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).