Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug
Bug#: 2645
Product:  
Component:  
Status: RESOLVED
Resolution: FIXED
Assigned To: Nathan Sidwell <nathan@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: pcarlini@unitus.it
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 2645 depends on: Show dependency tree
Show dependency graph
Bug 2645 blocks:

Additional Comments:






View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: Opened: 2001-04-25 13:36
This puzzle surfaced while analyzing Boost's testsuite
failure of call_traits_test.cpp.
That code assumes that two typedefs (for a const int&) are
equivalent to an explicit const int & in order to specify
a template type, but this is not the case for Gcc2.95.2
and Gcc3.0.
The following code, which does compile (and should not!),
illustrates the case:

template <typename T>
struct call_traits
{
public:
   typedef T type_less_spec;
};

template <typename T>
struct call_traits<T&>
{
   typedef T type_more_spec;
};


int main()
{
   int num;

   // Two typedefs lead to the instant. of the less spec. ("wrong") template
   typedef int& r_type;
   typedef const r_type cr_type;
   call_traits<cr_type>::type_less_spec var1 = num;
   //                    ^^^^^^^^^^^^^^

   // The explicit type leads to the instantiation of the "correct" one
   call_traits<const int&>::type_more_spec var2 = num;
   //                       ^^^^^^^^^^^^^^

   // As happen with a single typedef!
   typedef const int& std_cr_type;
   call_traits<std_cr_type>::type_more_spec var3 = num;

   
   // As happen, indeed, without the cv-qualifier
   call_traits<r_type>::type_more_spec var4;
}

Release:
3.0 20010423 (prerelease) & Codesourcery

Environment:
i686, Linux2.2.19, glibc2.2.2, binutils2.11

How-To-Repeat:
Before submitting the bug report, I cross checked with
two other (commonly believed) very ISO-compliant compilers,
which, indeed, rejected the testcase.

------- Comment #1 From pcarlini@unitus.it 2001-04-25 13:36 -------
Fix:
[nathan]
[8.3.2] says that cv qualifers are ignored on a reference
introduced via typdef/typename or tempate type arg. We
should do the same for restrict on non-pointer types for
consistency.
After discussion on the gcc list (http://gcc.gnu.org/ml/gcc/2001-04/msg01235.html)
the consensus is to do this with a warning for all cases
other than constifying a reference.

------- Comment #2 From pcarlini@unitus.it 2001-04-26 00:12 -------
From: Paolo Carlini <pcarlini@unitus.it>
To: gcc-gnats@gcc.gnu.org, pcarlini@unitus.it, nobody@gcc.gnu.org
Cc: landauer@apple.com
Subject: Re: c++/2645
Date: Thu, 26 Apr 2001 00:12:02 +0200

 --------------FCEFF1AD2F56FB11569E6057
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 Sorry for the confusion in the testcase (I badly mistaken a ref to a const int with a const ref
 
 to an int :(
 
 (thanks to Doug Landauer for pointing this out!)
 
 Therefore I cleaned up my testcase (which shows the Gcc problem) as follows:
 
 ----------------------
 
 template <typename T>
 
 struct call_traits
 
 {
 
 public:
 
    typedef T type_less_spec;
 
 };
 
 template <typename T>
 
 struct call_traits<T&>
 
 {
 
    typedef T type_more_spec;
 
 };
 
 int main()
 
 {
 
    int num;
 
    // Using two typedefs to specify a const & leads to the instant. of the less
 
    // specialized ("wrong") template
 
    typedef int& r_type;
 
    typedef const r_type cr_type;
 
    call_traits<cr_type>::type_less_spec var1 = num;
 
    //                    ^^^^^^^^^^^^^^
 
 
 
    // Without the cv-qualifier the more spec. ("right") template is instantiated
 
    call_traits<r_type>::type_more_spec var4;
 
    //                   ^^^^^^^^^^^^^^
 
 }
 
 ------------------
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=2645&database=gcc
 
 --------------FCEFF1AD2F56FB11569E6057
 Content-Type: text/html; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <html>
 
 <pre>Sorry for the confusion in the testcase (I badly mistaken a ref to a const int with a const ref</pre>
 
 <pre>to an int :(</pre>
 
 <pre>(thanks to Doug Landauer for pointing this out!)</pre>
 
 <pre></pre>
 
 <pre>Therefore I cleaned up my testcase (which shows the Gcc problem) as follows:</pre>
 
 <pre>----------------------</pre>
 
 <pre>template &lt;typename T></pre>
 
 <pre>struct call_traits</pre>
 
 <pre>{</pre>
 
 <pre>public:</pre>
 
 <pre>&nbsp;&nbsp; typedef T type_less_spec;</pre>
 
 <pre>};</pre>
 
 <pre></pre>
 
 <pre>template &lt;typename T></pre>
 
 <pre>struct call_traits&lt;T&amp;></pre>
 
 <pre>{</pre>
 
 <pre>&nbsp;&nbsp; typedef T type_more_spec;</pre>
 
 <pre>};</pre>
 
 <pre></pre>
 
 <pre>int main()</pre>
 
 <pre>{</pre>
 
 <pre>&nbsp;&nbsp; int num;</pre>
 
 <pre></pre>
 
 <pre>&nbsp;&nbsp; // Using two typedefs to specify a const &amp; leads to the instant. of the less</pre>
 
 <pre>&nbsp;&nbsp; // specialized ("wrong") template</pre>
 
 <pre>&nbsp;&nbsp; typedef int&amp; r_type;</pre>
 
 <pre>&nbsp;&nbsp; typedef const r_type cr_type;</pre>
 
 <pre>&nbsp;&nbsp; call_traits&lt;cr_type>::type_less_spec var1 = num;</pre>
 
 <pre>&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^^^^^^^^^^^^^^</pre>
 
 <pre>&nbsp;</pre>
 
 <pre>&nbsp;&nbsp; // Without the cv-qualifier the more spec. ("right") template is instantiated</pre>
 
 <pre>&nbsp;&nbsp; call_traits&lt;r_type>::type_more_spec var4;</pre>
 
 <pre>&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^^^^^^^^^^^^^^</pre>
 
 <pre>}</pre>
 
 <pre>------------------</pre>
 
 <pre></pre>
 
 <pre></pre>
 
 <pre></pre>
 
 <pre></pre>
 
 <pre><A HREF="http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=2645&database=gcc">http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&amp;pr=2645&amp;database=gcc</A></pre>
 
 <pre></pre>
 </html>
 
 --------------FCEFF1AD2F56FB11569E6057--
 

------- Comment #3 From Nathan Sidwell 2001-04-26 01:23 -------
State-Changed-From-To: open->analyzed
State-Changed-Why: confirmed. [8.3.2] says we should ignore the const
    when constifying a reference type via a typedef. i.e
    int & const thing; // ill-formed
    typedef int &ref_t;
    const ref_t thing; // ok, thing is int &
    
    ditto for volatile

------- Comment #4 From Nathan Sidwell 2001-04-26 08:23 -------
From: nathan@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org, pcarlini@unitus.it
Cc:  
Subject: Re: c++/2645
Date: 26 Apr 2001 08:23:29 -0000

 Synopsis: Boost-related const & typdef in template puzzle
 
 State-Changed-From-To: open->analyzed
 State-Changed-By: nathan
 State-Changed-When: Thu Apr 26 01:23:29 2001
 State-Changed-Why:
     confirmed. [8.3.2] says we should ignore the const
     when constifying a reference type via a typedef. i.e
     int & const thing; // ill-formed
     typedef int &ref_t;
     const ref_t thing; // ok, thing is int &
     
     ditto for volatile
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=2645&database=gcc

------- Comment #5 From Nathan Sidwell 2001-12-11 12:18 -------
Responsible-Changed-From-To: unassigned->nathan
Responsible-Changed-Why: patch in progress

------- Comment #6 From Nathan Sidwell 2001-12-11 20:18 -------
From: nathan@gcc.gnu.org
To: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
  nathan@gcc.gnu.org, nobody@gcc.gnu.org, pcarlini@unitus.it
Cc:  
Subject: Re: c++/2645: cvr qualifiers and typedef/typename/template reference types
Date: 11 Dec 2001 20:18:31 -0000

 Synopsis: cvr qualifiers and typedef/typename/template reference types
 
 Responsible-Changed-From-To: unassigned->nathan
 Responsible-Changed-By: nathan
 Responsible-Changed-When: Tue Dec 11 12:18:31 2001
 Responsible-Changed-Why:
     patch in progress
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=2645&database=gcc

------- Comment #7 From Nathan Sidwell 2002-02-22 04:13 -------
State-Changed-From-To: analyzed->closed
State-Changed-Why: 2002-02-19  Nathan Sidwell  <nathan@codesourcery.com>
    
    	PR c++/2645, DR 295
    	* cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals,
    	tf_keep_type_decl.
    	(make_typename_type): Use tsubst_flags_t.
    	* decl.c (make_typename_type): Adjust. Return non-artificial
    	TYPE_DECLs, if required.
    	(grokdeclarator): Simplify CVR qualification handling. Allow bad
    	qualifiers on typedef types.
    	* decl2.c (handle_class_head): Adjust make_typename_type call.
    	* parse.y (nested_name_specifier): Likewise.
    	(typename_sub0): Likewise.
    	(typename_sub1): Likewise.
    	* pt.c (convert_template_argument): Adjust make_typename_type
    	return value.
    	(tsubst): Adjust cp_build_qualified_type_real calls.
    	(check_cv_quals_for_unify): Cope with alowing bad qualifications
    	on template type parms.
    	(instantiate_decl): Recheck substitutions to give warnings on bad
    	qualifications.
    	* tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals.

------- Comment #8 From Nathan Sidwell 2003-04-10 12:20 -------
State-Changed-From-To: closed->analyzed
State-Changed-Why: I will look at this again

------- Comment #9 From Nathan Sidwell 2003-04-19 18:58 -------
State-Changed-From-To: analyzed->closed
State-Changed-Why: afaict 3.3 & 3.4 do the right thing

Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug