Bug 13640 - Failing to reject class template partial specialization which can never be selected
Summary: Failing to reject class template partial specialization which can never be se...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
: 7033 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-01-10 20:08 UTC by Giovanni Bajo
Modified: 2021-05-26 19:44 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-01-10 20:44:29


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Giovanni Bajo 2004-01-10 20:08:28 UTC
This is basically c++/7033, cleaned and simplified. Comment 6 (quoting myself):

---------------------------------------------------------------------------
 I'm confident that defining a partial template
 specialization whose arguments can't be fully deduced from the arguments of
 the original template is ill-formed. In fact, GCC correctly rejects this:
 
 -----------------------------------------------
 template <class> struct K;
 
 template <class T>
 struct K<int> {};
 -----------------------------------------------
 pr7033.cpp:4: error: template parameters not used in partial specialization:
 pr7033.cpp:4: error:         `T'
 
 but it fails to reject this:
 
 -----------------------------------------------
 template <typename, typename> struct S;
 
 template <template <typename> class C,
 typename T,
 typename V>
 struct S<C<T>,typename C<T>::template it<V> > {};
 -----------------------------------------------
 
 which is currently accepted by 3.3 and 3.4, even if "V" is used only in
 non-deduced contexts. This is a regression (rechecked on CVS 20050305 for
 both 3.3 and 3.4) with respect to 2.95 which was rejecting the code:
 
 pr7033.cpp:6: template parameters not used in partial specialization:
 pr7033.cpp:6:         `V'
 
 (actually, the error message could be "template parameter used in
 non-decuded context", but anyway).
 
 This is an accepts-invalid regression, and I now flagged it as such.
---------------------------------------------------------------------------

I am not sure the code is ill-formed. Maybe the specialization can be created 
but it makes no sense. Since we *used* to reject this, and we are silently
accepting it now, we still have a regression. At the very least, we should
emit a friendly warning for the user.
Comment 1 Giovanni Bajo 2004-01-10 20:10:13 UTC
*** Bug 7033 has been marked as a duplicate of this bug. ***
Comment 2 Andrew Pinski 2004-01-10 20:44:29 UTC
Confirmed, this has been failing since at least 2000-12-31.
Comment 3 Steven Bosscher 2004-01-10 22:24:02 UTC
This has been broken for a very long time.  No 3.x compiler has properly 
rejected this.  So IMO this is not a showstopper for 3.4 and as such it should 
not be targeted for 3.4.0.  Therefore I'm moving the target milestone to 3.5.  
Comment 4 Gabriel Dos Reis 2004-01-10 23:25:39 UTC
Subject: Re:  New: [3.3/3.4 regression] Failing to reject class template partial specialization which can never be selected

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:

| This is basically c++/7033, cleaned and simplified. Comment 6 (quoting myself):
| 
| ---------------------------------------------------------------------------
|  I'm confident that defining a partial template
|  specialization whose arguments can't be fully deduced from the arguments of
|  the original template is ill-formed. In fact, GCC correctly rejects this:

I disagree.  Declaring/defining a partial specialization that can
never be selected by partial ordering is not ill-formed.

|  -----------------------------------------------
|  template <class> struct K;
|  
|  template <class T>
|  struct K<int> {};
|  -----------------------------------------------
|  pr7033.cpp:4: error: template parameters not used in partial specialization:
|  pr7033.cpp:4: error:         `T'

That situation is different.  There is a note somewhere in the standard
saying that every template parameter shall be used in a partial
specialization.  However, that note does not imply that the resulting
partial specialization could ever be selected by partial ordering or
template argument deduction.

|  but it fails to reject this:
|  
|  -----------------------------------------------
|  template <typename, typename> struct S;
|  
|  template <template <typename> class C,
|  typename T,
|  typename V>
|  struct S<C<T>,typename C<T>::template it<V> > {};
|  -----------------------------------------------

I'm well aware of this example -- as I used it to discuss related
topics on the committee reflector.

|  which is currently accepted by 3.3 and 3.4, even if "V" is used only in

And that is allowed by the standard.

|  non-deduced contexts. This is a regression (rechecked on CVS 20050305 for
|  both 3.3 and 3.4) with respect to 2.95 which was rejecting the code:
|  
|  pr7033.cpp:6: template parameters not used in partial specialization:
|  pr7033.cpp:6:         `V'

That is a bogus behaviour.

|  (actually, the error message could be "template parameter used in
|  non-decuded context", but anyway).
|  
|  This is an accepts-invalid regression, and I now flagged it as such.

I disagree: it is not accepts-invalid.  

-- Gaby
Comment 5 Gabriel Dos Reis 2004-01-10 23:26:43 UTC
Subject: Re:  [3.3/3.4 regression] Failing to reject class template partial specialization which can never be selected

"steven at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| This has been broken for a very long time.  No 3.x compiler has properly 
| rejected this.  So IMO this is not a showstopper for 3.4 and as such it should 
| not be targeted for 3.4.0.  Therefore I'm moving the target milestone to 3.5.  

You may close it as well -- it is not reject-invalid.  See my previous
comment. 

-- Gaby
Comment 6 Andrew Pinski 2004-01-10 23:34:22 UTC
Closing as invalid per Gaby.
Comment 7 Giovanni Bajo 2004-01-11 00:11:08 UTC
I can easily agree that we are not non-conforming, but then I want this open as 
an enhancement request. We actually got a bug report about this, and it makes 
sense to issue a warning on such cases. 

Unless you show me that such a warning could actually be generated in cases 
where it's an annoyance. I thought of it but nothing came to my mind.
Comment 8 Gabriel Dos Reis 2004-01-11 00:18:59 UTC
Subject: Re:  [3.3/3.4 regression] Failing to reject class template partial specialization which can never be selected

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:

| Unless you show me that such a warning could actually be generated in cases 
| where it's an annoyance. I thought of it but nothing came to my mind.

Well, I guess if you look at some boost-like codes, you might find
some occurances.  But, I have no problem having it open -- if that
makes you happy.  However I disgaree with the classification that it
is accept-invalid.  And if you're going to make that a warning, please
put it off by default, because that is going to waste cycles and increase
compile-time -- because, you'll need to do partial template ordering.

-- Gaby
Comment 9 Gabriel Dos Reis 2004-01-11 00:19:54 UTC
Subject: Re:  Failing to reject class template partial specialization which can never be selected

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:

|            What    |Removed                     |Added
| ----------------------------------------------------------------------------
|            Severity|normal                      |enhancement

So what is this?  A warning thingy or not?
Comment 10 Giovanni Bajo 2004-01-11 00:45:27 UTC
Subject: Re:  Failing to reject class template partial specialization which can never be selected

gdr at integrable-solutions dot net wrote:

>> ----------------------------------------------------------------------------
>>            Severity|normal                      |enhancement
>
> So what is this?  A warning thingy or not?

Yes. If it's not a big problem, I'll keep it open with the lowest priority as
an enhancement.

Giovanni Bajo


Comment 11 Andrew Pinski 2004-01-11 03:12:16 UTC
No need for diagnostic as we do use V and it makes GCC overly warning about things 
which do not exist.
Comment 12 Wolfgang Bangerth 2004-01-12 15:56:00 UTC
This should be kept open. There _is_ a bug. 
W. 
Comment 13 Theodore.Papadopoulo 2004-01-15 19:49:27 UTC
Subject: Re:  Failing to reject class template partial specialization which can never be selected 


[Sorry, late reply]

The only thing I can add is that it is extremely awkward for a user 
to have a piece of code that is accepted by the compiler (as I 
understand it should do) and that is silently discarded (this is not 
what is done but the observed behaviour is the same).

I understand that emitting the warning might be costly, but emitting 
nothing is very error prone and confusing.

The following is pure speculation but I assume there are two ways of 
implementing the warning:

- Make the check when the template specialization is parsed. Here I 
think I understand that we do not want the partial ordering to be done.

- Make the check when one tries to instantiate the template. At this 
point, the partial ordering of the specialization has anyway to be 
done if I understand correctly, so emitting a warning at this stage 
should not be very costly. The warning would only be emitted when an 
attempt to use the code is made and not otherwise, but that should be 
both cost effective and non surprising as one is used to not have 
full error messages on template classes as long as those are not used.

All that being said, I still believe that this is a quite annoying 
limitation in C++ and one that cannot be overcomed easily.  But this 
is not the topic here.

--------------------------------------------------------------------
Theodore Papadopoulo
Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------


Comment 14 Gabriel Dos Reis 2004-03-01 00:48:29 UTC
(In reply to comment #12)
> This should be kept open. There _is_ a bug. 
> W. 

What is that bug?  I fully agree with the warning enhancement, but bug?
Comment 15 Giovanni Bajo 2004-03-01 01:14:35 UTC
(In reply to comment #8)

> And if you're going to make that a warning, please
> put it off by default, because that is going to waste cycles and increase
> compile-time -- because, you'll need to do partial template ordering.

I'm looking into a simple sintactic solution. Within 
process_partial_specialization, I go through the inner_args and check if the 
template parameters appear only in non-deduced contexts (for a start: within 
nested-name-specifiers). If that's true, I emit a warning. Am I missing 
something? It looks like it's going to work.
Comment 16 Gabriel Dos Reis 2004-03-01 01:31:14 UTC
Subject: Re:  Failing to reject class template partial specialization which can never be selected

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:

| (In reply to comment #8)
| 
| > And if you're going to make that a warning, please
| > put it off by default, because that is going to waste cycles and increase
| > compile-time -- because, you'll need to do partial template ordering.
| 
| I'm looking into a simple sintactic solution. Within 
| process_partial_specialization, I go through the inner_args and check if the 
| template parameters appear only in non-deduced contexts (for a start: within 
| nested-name-specifiers). If that's true, I emit a warning. Am I missing 
| something? It looks like it's going to work.

Yes, essentially, something like that should catch many of the
non-deducible contexts use (note that real argument deduction process
may fail for other reasons).  I don't know whether you may reduce the
computational complexity by caching the "deducibility" property
(otherwise, it sounds like you're describing an algorith, that would
quadratic).  On the other hand, I would expect people using that
falg not (ab)using deep template-arguments lists.

-- Gaby