Bug 3518 - default conversion to pointer-to-function is applied to soon (related to DR295)
Summary: default conversion to pointer-to-function is applied to soon (related to DR295)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P3 normal
Target Milestone: 4.0.0
Assignee: Nathan Sidwell
URL:
Keywords: rejects-valid
Depends on: 10807
Blocks:
  Show dependency treegraph
 
Reported: 2001-07-01 13:26 UTC by Nathan Sidwell
Modified: 2004-04-05 15:55 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-03-26 06:36:19


Attachments
2810-2.ii (107 bytes, text/plain)
2003-05-21 15:16 UTC, Nathan Sidwell
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Sidwell 2001-07-01 13:26:00 UTC
 In the attached file Foo1 should fail as [8.5]/14 applies to the
 return value. But before looking for ctors of any, ocp_convert does a
 default conversion and decays the function to a pointer. It should
 fail, because the applicable ctor attempts to make a const qualified
 function type.

Release:
2.95 -> 3.4

Environment:
i686-pc-linux-gnu
Comment 1 Nathan Sidwell 2002-09-13 16:30:13 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: confirmed
Comment 2 Wolfgang Bangerth 2002-11-26 09:55:24 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c++/3518: default conversion applied too soon
Date: Tue, 26 Nov 2002 09:55:24 -0600 (CST)

 As Nathan notes in the other report, this may be related to PR 7477.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:           bangerth@ticam.utexas.edu
                                www: http://www.ticam.utexas.edu/~bangerth
 
 
Comment 3 Giovanni Bajo 2003-05-15 11:00:10 UTC
State-Changed-From-To: analyzed->feedback
State-Changed-Why: Nathan, I see what you are saying but I think the code is
    still legal. The applicable ctor is attempting to create
    a const qualified _reference_ to function type, which is
    a valid type. In fact, other compilers like Comeau/EDG
    instanciate the constructor with [T = void(void)]. 
    GCC compiles the code, but applies the default conversion
    too soon, so instanciates the template with [T = (void)(*)(void)]
    which is wrong. If you agree, we can rework a code snippet
    which fails if T is a function pointer so that we can
    properly detect the bug.
Comment 4 Nathan Sidwell 2003-05-15 12:23:46 UTC
From: Nathan Sidwell <nathan@codesourcery.com>
To: giovannibajo@libero.it, gcc-bugs@gcc.gnu.org, nathan@codesourcery.com,
   nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c++/3518: [2003-05-03] default conversion applied too soon
Date: Thu, 15 May 2003 12:23:46 +0100

 giovannibajo@libero.it wrote:
 > Old Synopsis: [2003-01-02] default conversion applied too soon
 > New Synopsis: [2003-05-03] default conversion applied too soon
 > 
 > State-Changed-From-To: analyzed->feedback
 > State-Changed-By: bajo
 > State-Changed-When: Thu May 15 11:00:10 2003
 > State-Changed-Why:
 >     Nathan, I see what you are saying but I think the code is
 >     still legal. The applicable ctor is attempting to create
 >     a const qualified _reference_ to function type, which is
 >     a valid type. In fact, other compilers like Comeau/EDG
 >     instanciate the constructor with [T = void(void)]. 
 >     GCC compiles the code, but applies the default conversion
 >     too soon, so instanciates the template with [T = (void)(*)(void)]
 >     which is wrong. If you agree, we can rework a code snippet
 >     which fails if T is a function pointer so that we can
 >     properly detect the bug.
 sure. Thre are two other issues that gcc might not
 have got right then.
 1) you can ignore the cv qualifier on a reference when that reference
 is introduced by a typedef or template type parm
 2) DR 295 made the same change for function types
 
 nathan
 
 -- 
 Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
           The voices in my head said this was stupid too
 nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk
 
 
Comment 5 Giovanni Bajo 2003-05-15 18:20:44 UTC
State-Changed-From-To: feedback->analyzed
State-Changed-Why: Ok. I have submitted a new PR (c++/10807) with a testcase
    suming up the whole DR295. This PR is directly related:
    probably when DR295 is implemented correctly, this PR will
    be fixed as well. Anyway, the final testcase for this PR
    is:
    
    -----------------------------------------------
    template <typename T>
    struct check_not_pointer {};
    
    template <typename T>
    struct check_not_pointer<T*>;
    
    struct any
    {
      template <typename T> any (const T&)
      {
          check_not_pointer<T> dummy;
      }
    };
    
    template <typename T> any Foo (const T &s)
    {
        return s;
    }
    
    void f ()
    {}
    
    int main()
    {
      Foo (f);
    }
    -----------------------------------------------
    pr3518.cpp: In constructor `any::any(const T&) [with T = void (*)()]':
    pr3518.cpp:17:   instantiated from `any Foo(T&) [with T = void ()()]'
    pr3518.cpp:25:   instantiated from here
    pr3518.cpp:11: error: `dummy' has incomplete type
    pr3518.cpp:11: error: storage size of `dummy' isn't known
    
    It fails because any::any should be instantiates with
    [T = void (void)], while it gets instantiated with [T = void(*)(void)]
    because the default conversion is applied too soon (and
    DR295 is not implemented).
Comment 6 Nathan Sidwell 2004-04-02 15:27:59 UTC
Here is a shorted test case.
template <typename T> void Foo (const T &);
template <typename T> void Baz (const T (*)());

int &f ();

int main()
{
  Foo (f);
  Baz (f);
}

AFAICT either both calls are good, or both are bad. edg 3.3 accepts the first,
but not the second. I'm asking John Spicer why.
Comment 7 Nathan Sidwell 2004-04-02 15:30:39 UTC
If those calls are deduceable, then the deductions will involve
ignoring a cv qualifier on either a function type (Foo), or reference
type (Baz).  As we're not permitted to do that in deduction, then both
should fail, shouldn't they?

EDG 3.3 accepts the call for Foo, but rejects that of Baz.  I
do not understand why. Prior to fixing g++ bug 14007, g++ accepted
both calls, now it rejects both calls.

In Foo's case we are deducing the arguments from a function call, and
14.8.2.1 applies. p2 tells us to use 'const T' for deduction against an
A of 'int &()'. Why does this deduction succeed with T being 'int & ()'?
p3 tells us that the deduced A can be more cv qualified, but for that to
apply we must actually have a deduced A, and I can't see how we get there.
Comment 8 Wolfgang Bangerth 2004-04-02 15:35:22 UTC
In response to comment #6: I may be ignorant of special rules for function 
pointers, but when you call Baz(f) you call it with a _reference_ to a  
function as argument. However, Baz takes a _pointer_, so you would have to 
perform a conversion of the argument. Should this really be done here 
even for template arguments? 
 
W. 
Comment 9 GCC Commits 2004-04-05 15:52:23 UTC
Subject: Bug 3518

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	nathan@gcc.gnu.org	2004-04-05 15:52:12

Modified files:
	gcc/cp         : ChangeLog pt.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/template: unify7.C 

Log message:
	cp:
	PR c++/3518
	* pt.c (check_cv_quals_for_unify): Ignore bogus CV quals at outer
	level.
	testsuite:
	PR c++/3518
	* g++.dg/template/unify7.C: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4028&r2=1.4029
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.846&r2=1.847
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3652&r2=1.3653
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/unify7.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 10 Nathan Sidwell 2004-04-05 15:53:03 UTC
2004-04-05  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/3518
	* pt.c (check_cv_quals_for_unify): Ignore bogus CV quals at outer
	level.
Comment 11 GCC Commits 2004-06-21 12:46:43 UTC
Subject: Bug 3518

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	nathan@gcc.gnu.org	2004-06-21 12:46:29

Modified files:
	gcc/cp         : ChangeLog pt.c tree.c 
	gcc/testsuite  : ChangeLog 
	gcc/testsuite/g++.dg/template: qualttp20.C 
	gcc/testsuite/g++.old-deja/g++.jason: report.C 
	gcc/testsuite/g++.old-deja/g++.other: qual1.C 
Added files:
	gcc/testsuite/g++.dg/template: unify5.C unify6.C unify7.C 

Log message:
	cp:
	PR c++/3518
	* pt.c (check_cv_quals_for_unify): Ignore bogus CV quals at outer
	level.
	
	PR c++/14007
	* pt.c (check_cv_quals_for_unify): Correct logic for disallowed
	cv-qualifier unification.
	* tree.c (cp_build_qualified_type_real): Renable DR295 logic.
	testsuite:
	PR c++/3518
	* g++.dg/template/unify7.C: New.
	
	PR c++/14007
	* g++.dg/template/unify5.C: New.
	* g++.dg/template/unify6.C: New.
	* g++.dg/template/qualttp20.C: Adjust.
	* g++.old-deja/g++.jason/report.C: Adjust.
	* g++.old-deja/g++.other/qual1.C: Adjust.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.125&r2=1.3892.2.126
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.816.2.31&r2=1.816.2.32
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.360.4.6&r2=1.360.4.7
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.212&r2=1.3389.2.213
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/unify5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.18.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/unify6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.18.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/unify7.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.18.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/qualttp20.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.4&r2=1.4.32.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.jason/report.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.10&r2=1.10.16.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.other/qual1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.5&r2=1.5.16.1