User account creation filtered due to spam.

Bug 19404 - [4.0 Regression] anonymous types and templates and rejecting valid code
Summary: [4.0 Regression] anonymous types and templates and rejecting valid code
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
: 21426 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-01-12 18:46 UTC by André Wöbbeking
Modified: 2005-05-06 20:16 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-01-12 18:53:44


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description André Wöbbeking 2005-01-12 18:46:14 UTC
Hi, 
 
the following Code doesn't compile: 
 
 
class Base; 
 
 
template<typename Type> 
inline 
Base& 
operator<<(Base& rConfiguration, 
           Type const& rType) 
{ 
    return rConfiguration; 
} 
 
 
template<typename Type> 
inline 
Base const& 
operator>>(Base const& rConfiguration, 
           Type& rType) 
{ 
    return rConfiguration; 
} 
 
 
struct QSizePolicy 
{ 
    enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize }; 
 
    enum SizeType { Fixed = 0 }; 
 
    SizeType verData() const { return (SizeType)( (data & VMask) >> HSize ); } 
 
    void setVerData( SizeType d ) { data = (unsigned int)(data & ~(HMask << 
HSize)) | 
        (d << HSize); } 
 
    unsigned int data; 
}; 
 
It compiles with g++ < 4.0. 
 
 
Cheers, 
André
Comment 1 Andrew Pinski 2005-01-12 18:53:44 UTC
Confirmed, reduced testcase:
class Base; 
template<typename Type> 
inline  Base const& operator>>(Base const& rConfiguration, Type& rType) ;
enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize }; 
int verData(unsigned int data){ return (int)( (data & VMask) >> HSize ); } 

Note it start failing after "2004-12-11".

This is valid code we should reject the template as it does not fit with the arguments.
Comment 2 Andrew Pinski 2005-01-12 20:35:44 UTC
The only patch which makes sense (as it is not really that bogus really as shown in this example):
        PR c++/17413
        * pt.c (check_instantiated_args): Remove bogus SFINAE code.
Comment 3 Mark Mitchell 2005-01-31 06:22:13 UTC
This code is invalid.  The use of ">>" requires the instantiation of the
declaration of the overloaded "operator>>", but that instantiation fails because
one of the template argument is anonymous.
Comment 4 Lars Knoll 2005-04-08 14:36:47 UTC
Hi Mark, 
 
(In reply to comment #3) 
> This code is invalid.  The use of ">>" requires the instantiation of the 
> declaration of the overloaded "operator>>", but that instantiation fails 
because 
> one of the template argument is anonymous. 
 
I don't see why the code is invalid. If you leave out the forward declaration 
of the template operator everything compiles fine, as the values in the 
anonymous enum get cast to integers, and the builtin operator>>(int, int) 
applies. 
 
So this compiles just fine (and to the correct code as far as I can tell): 
enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize };  
int verData(unsigned int data){ return (int)( (data & VMask) >> HSize ); }  
 
while this doesn't: 
 
class Base;  
template<typename Type>  
inline  Base const& operator>>(Base const& rConfiguration, Type& rType) ; 
enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize };  
int verData(unsigned int data){ return (int)( (data & VMask) >> HSize ); }  
 
The types in the forward declaration have no connection whatsoever with the 
values in the anonymous union, so the template should not apply. 
 
Lars 
 
Comment 5 Mark Mitchell 2005-04-08 15:34:20 UTC
Subject: Re:  [4.0 Regression] anonymous types and templates
 and rejecting valid code

lars at trolltech dot com wrote:
> ------- Additional Comments From lars at trolltech dot com  2005-04-08 14:36 -------
> Hi Mark, 
>  
> (In reply to comment #3) 
> 
>>This code is invalid.  The use of ">>" requires the instantiation of the 
>>declaration of the overloaded "operator>>", but that instantiation fails 
> 
> because 
> 
>>one of the template argument is anonymous. 
> 
>  
> I don't see why the code is invalid. If you leave out the forward declaration 
> of the template operator everything compiles fine, as the values in the 
> anonymous enum get cast to integers, and the builtin operator>>(int, int) 
> applies. 

Lars --

As I said earlier in the thread, there is now an open DR about this 
issue.  So, it might be resolved either way, eventually.

But, what the standard says at present is that you do overload 
resolution on both operators.  That requires that you instantiate their 
declarations, and the instantiation of the one using anonymous enums is 
invalid.  There's nothing in the standard that says that you discard 
instantiations that don't work -- except in cases of SFINAE.  And SFINAE 
does not let you ignore all errors, as some people think; it's a very 
specific set.

Comment 6 Lars Knoll 2005-04-08 16:35:43 UTC
Subject: Re:  [4.0 Regression] anonymous types and templates and rejecting valid code

On Friday 08 April 2005 17:34, mark at codesourcery dot com wrote:
> ------- Additional Comments From mark at codesourcery dot com  2005-04-08
> 15:34 ------- Subject: Re:  [4.0 Regression] anonymous types and templates
>  and rejecting valid code
>
> lars at trolltech dot com wrote:
> > ------- Additional Comments From lars at trolltech dot com  2005-04-08
> > 14:36 ------- Hi Mark,
> >
> > (In reply to comment #3)
> >
> >>This code is invalid.  The use of ">>" requires the instantiation of the
> >>declaration of the overloaded "operator>>", but that instantiation fails
> >
> > because
> >
> >>one of the template argument is anonymous.
> >
> > I don't see why the code is invalid. If you leave out the forward
> > declaration of the template operator everything compiles fine, as the
> > values in the anonymous enum get cast to integers, and the builtin
> > operator>>(int, int) applies.
>
> Lars --
>
> As I said earlier in the thread, there is now an open DR about this
> issue.  So, it might be resolved either way, eventually.

Sorry, I didn't see the connection clearly. I was just wondering as we got a 
few bug reports about compile failures using Qt with gcc 4.

> But, what the standard says at present is that you do overload
> resolution on both operators.  That requires that you instantiate their
> declarations, and the instantiation of the one using anonymous enums is
> invalid.  There's nothing in the standard that says that you discard
> instantiations that don't work -- except in cases of SFINAE.  And SFINAE
> does not let you ignore all errors, as some people think; it's a very
> specific set.

I haven't read the standard to that level I have to admit :)

But if this invalid instantiation can't be ignored it seems to mean to me that 
one can not use any anonymous enum in C++ (better in a C++ header), as you 
would get compile errors as soon as someone uses a template to overload an 
operator that happens to be used together with values in the enum.

Cheers,
Lars
Comment 7 Paolo Carlini 2005-04-27 09:15:35 UTC
*** Bug 21244 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2005-05-06 20:16:46 UTC
*** Bug 21426 has been marked as a duplicate of this bug. ***