Bug 39310

Summary: T const assumed to be compatible with int (A::*) (void) const
Product: gcc Reporter: Dodji Seketeli <dodji>
Component: libstdc++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: dodji, fang, gcc-bugs, jason, paolo
Priority: P3    
Version: unknown   
Target Milestone: 4.4.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 37806    
Attachments: Fix for is_member_function_pointer and GCC
New fix that adds function cv-qual handling to is_function, and fixes compiler to allow that

Description Dodji Seketeli 2009-02-26 13:55:28 UTC
In the test file libstdc++-v3/testsuite/tr1/4_metaprogramming/is_member_function_pointer/value.cc, the test
VERIFY( (test_category<is_member_function_pointer, int (ClassType::*) (int) const>(true)) );
should not PASS IMO.

It passes today because of a bug in gcc. More on this in some comments to come below.

Why shouldn't it PASS ?

Consider:
struct remove_const<T> {};
struct remove_const<T const> 
{
  typedef T type;
};


The  is_member_function_pointer template in the value.cc is written based on the assumption that the T in the template parameter of

struct remove_const<T const> 
{
  typedef T type;
};

Should deduce to int (A::*) (void), when we try to instantiate 
remove_const<int (A::*) (void) const>; Hence, the current implementation of is_member_function_pointer assumes that 
struct remove_const<T const> 
{
  typedef T type;
};
should be intantiated.

Actually T const is not compatible with int (A::*) (void) vonst; So it's the template struct remove_const<T> {}; that should be instantiated. Not its specialization.

So the test VERIFY( (test_category<is_member_function_pointer,
int (ClassType::*) (int) const>(true)) ); should not PASS.

I will paste in the comments a patch to apply to GCC so that it doesn't compile that test.
Comment 1 Jason Merrill 2009-02-26 16:56:08 UTC
Created attachment 17367 [details]
Fix for is_member_function_pointer and GCC

Rather, the test should pass, but we need to fix is_member_function_pointer so it will still pass without the GCC bug.  Patch attached.
Comment 2 Dodji Seketeli 2009-02-27 20:08:28 UTC
I have filed bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39321 that describes the gcc bug. It also has a patch that should fix it.
Comment 3 Jason Merrill 2009-03-02 01:47:01 UTC
The discussion of Core issue 547 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#547) suggests that we ought to be able to write partial specializations of is_function that can deal with function cv-quals.
Comment 4 Jason Merrill 2009-03-02 20:09:34 UTC
Created attachment 17389 [details]
New fix that adds function cv-qual handling to is_function, and fixes compiler to allow that

Here's a fix along those lines.
Comment 5 Paolo Carlini 2009-03-03 08:02:58 UTC
Hi. I'll try to catch up as soon as possible on the details of (the v3 bits of) this issue, but first blush it seems real strange to me that we cannot implement anymore the is_member_pointer trait as an OR of the is_member_object_pointer and the is_member_function_pointer traits. Can I have a quick "executive report" about the rationale of this part of the proposed fix?
Comment 6 Jason Merrill 2009-03-03 13:08:27 UTC
Subject: Re:  T const assumed to be compatible with int
 (A::*) (void) const

paolo dot carlini at oracle dot com wrote:
> it seems real strange to me that we cannot
> implement anymore the is_member_pointer trait as an OR of the
> is_member_object_pointer and the is_member_function_pointer traits.

We can still implement it that way; that part of the patch is just an 
optimization.  I'm can drop it if you prefer.

Comment 7 Paolo Carlini 2009-03-03 15:46:05 UTC
Thanks, Jason, now I see it. Then I'm Ok with the patch as-is.
Comment 8 Paolo Carlini 2009-03-13 17:39:31 UTC
Jason, are you going to commit the is_member-2.patch?
Comment 9 Jason Merrill 2009-03-15 01:45:42 UTC
I was planning to wait until 4.4 branches.  If you'd rather have it in 4.4, I can commit it now.
Comment 10 Paolo Carlini 2009-03-15 02:07:32 UTC
(In reply to comment #9)
> I was planning to wait until 4.4 branches.  If you'd rather have it in 4.4, I
> can commit it now.

Well, if you ask me, yes, I would like to see it in 4.4. Thanks in advance. 
Comment 11 Jason Merrill 2009-03-31 18:31:47 UTC
Subject: Bug 39310

Author: jason
Date: Tue Mar 31 18:31:17 2009
New Revision: 145365

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145365
Log:
        PR c++/37806
        * typeck.c (cp_apply_type_quals_to_decl): Don't apply any quals
        to a typedef.
        * tree.c (cp_build_qualified_type_real): Don't apply restrict to a
        function type.
        * decl.h (enum decl_context): Add TEMPLATE_TYPE_ARG.
        * decl.c (groktypename): Add is_template_arg parameter.
        (grokdeclarator): Allow function cv-quals on a template type arg.
        * parser.c (cp_parser_new_type_id, cp_parser_type_id): Add
        is_template_arg argument in calls to groktypename.
        * cp-tree.h: Adjust prototype.
        * error.c (dump_type_prefix, dump_type_suffix): Fix plain
        FUNCTION_TYPE printing.

        PR libstdc++/39310
        * include/tr1_impl/type_traits (is_function): Add partial
        specializations with function cv-quals.
        (__is_function_helper): Remove.
        (is_member_pointer): Don't define in terms of is_member_*_pointer.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl.h
    trunk/gcc/cp/error.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/tree.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/g++.dg/template/qualttp20.C
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/tr1_impl/type_traits

Comment 12 Dodji Seketeli 2009-04-02 14:19:08 UTC
Fixed in trunk (gcc 4.5).
Comment 13 Jason Merrill 2009-04-07 04:38:25 UTC
Subject: Bug 39310

Author: jason
Date: Tue Apr  7 04:38:10 2009
New Revision: 145648

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145648
Log:
        * decl.c (grokdeclarator): Reject pointer to qualified function
        type.

        PR c++/37806, core issue 547
        * typeck.c (cp_apply_type_quals_to_decl): Don't apply any quals
        to a typedef.
        * tree.c (cp_build_qualified_type_real): Don't apply restrict to a
        function type.
        * decl.h (enum decl_context): Add TEMPLATE_TYPE_ARG.
        * decl.c (groktypename): Add is_template_arg parameter.
        (grokdeclarator): Allow function cv-quals on a template type arg.
        * parser.c (cp_parser_new_type_id, cp_parser_type_id): Add
        is_template_arg argument in calls to groktypename.
        * cp-tree.h: Adjust prototype.
        * error.c (dump_type_prefix, dump_type_suffix): Fix plain
        FUNCTION_TYPE printing.

        PR libstdc++/39310
        * include/tr1_impl/type_traits (is_function): Add partial
        specializations with function cv-quals.
        (__is_function_helper): Remove.
        (is_member_pointer): Don't define in terms of is_member_*_pointer.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/other/typedef2.C
      - copied unchanged from r145367, trunk/gcc/testsuite/g++.dg/other/typedef2.C
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef17.C
      - copied unchanged from r145367, trunk/gcc/testsuite/g++.dg/template/typedef17.C
Modified:
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/cp-tree.h
    branches/gcc-4_4-branch/gcc/cp/decl.c
    branches/gcc-4_4-branch/gcc/cp/decl.h
    branches/gcc-4_4-branch/gcc/cp/error.c
    branches/gcc-4_4-branch/gcc/cp/parser.c
    branches/gcc-4_4-branch/gcc/cp/tree.c
    branches/gcc-4_4-branch/gcc/cp/typeck.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/qualttp20.C
    branches/gcc-4_4-branch/libstdc++-v3/ChangeLog
    branches/gcc-4_4-branch/libstdc++-v3/include/tr1_impl/type_traits

Comment 14 Paolo Carlini 2009-04-07 08:51:48 UTC
Fixed for 4.4.0 too. Thanks Jason.