Bug 61182 - [4.9/4.10 Regression] Forming pointer to qualified function type
Summary: [4.9/4.10 Regression] Forming pointer to qualified function type
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 4.9.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-05-13 20:03 UTC by blastrock
Modified: 2014-05-27 20:13 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Minimal test (307 bytes, text/x-c++src)
2014-05-13 20:03 UTC, blastrock
Details

Note You need to log in before you can comment on or make changes to this bug.
Description blastrock 2014-05-13 20:03:00 UTC
Created attachment 32793 [details]
Minimal test

The attached code does not compile on gcc 4.9 but compiles on clang 3.4 and gcc < 4.9.

Accessor decompose the type with C = "C" and T = "int () const" in the first call of make. Then same_type creates a T* and removes the pointer to get back to the same type. GCC 4.9 complains that we cannot create a pointer to a qualified pointer type even though we never instanciate it.
Comment 1 Paolo Carlini 2014-05-13 20:24:13 UTC
I don't understand how this is legal, but certainly the behavior of the front-end changed with r198160, committed to resolve c++/48665. Adding Jason in CC.
Comment 2 Paolo Carlini 2014-05-13 20:57:07 UTC
In fact, icc, clang, and SolarisStudio appear to accept pointers to qualified function types?!?
Comment 3 blastrock 2014-05-13 21:20:09 UTC
I am no c++ expert but my guess is that it should be allowed to have qualified function types as long as you don't try to instantiate that type.

The problem in our code is that we use boost::remove_const (which should be a noop in this case I believe) which uses a trick involving pointers similar to what I wrote in the attached example and does not compile with 4.9.

Still, if the standard says that it is not allowed we can work around it, but then should I file a bug to clang?
Comment 4 Paolo Carlini 2014-05-13 21:29:35 UTC
I think we want first to hear from Jason, because over the years Core handled a number of DRs in this area, eg Core/295.
Comment 5 Jason Merrill 2014-05-14 03:12:38 UTC
8.3.5/6 says,

A function type with a cv-qualifier-seq or a ref-qualifier ... shall appear only as:
— the function type for a non-static member function,
— the function type to which a pointer to member refers,
— the top-level function type of a function typedef declaration or alias-declaration,
— the type-id in the default argument of a type-parameter (14.1), or
— the type-id of a template-argument for a type-parameter (14.3.1).

Which I read as meaning no (non-member) pointers to such a type.
Comment 6 Paolo Carlini 2014-05-14 09:05:02 UTC
Thanks. I was also going through that section (together with Core/1417 submitted by Daniel, and other issues) and indeed, not having followed this tangle of issues of the years I was tempted to interpret it the same way. I'm adding Daniel in CC, maybe he has a something to say. To be safe, I'm also tentatively marking this as a regression.
Comment 7 Jonathan Wakely 2014-05-14 10:55:51 UTC
(In reply to pdaouadi from comment #3)
> Still, if the standard says that it is not allowed we can work around it,
> but then should I file a bug to clang?

And Boost. I have to wonder why their remove_const is so much more complicated than ours:

  template<typename _Tp>
    struct remove_const
    { typedef _Tp     type; };

  template<typename _Tp>
    struct remove_const<_Tp const>
    { typedef _Tp     type; };

That doesn't need to form a pointer then remove it again, so works with function types.
Comment 8 Daniel Krügler 2014-05-14 11:01:33 UTC
(In reply to Paolo Carlini from comment #6)
> I'm adding Daniel in CC, maybe he has a something to say. To be safe, I'm
> also tentatively marking this as a regression.

I agree with Jason as well for the reasons the quoted CWG issue 1417 had clarified. This is also one reason, why the current library specification of std::add_pointer needs to be corrected, see

http://cplusplus.github.io/LWG/lwg-active.html#2101
Comment 9 Daniel Krügler 2014-05-14 11:07:01 UTC
(In reply to Jonathan Wakely from comment #7)
> And Boost. I have to wonder why their remove_const is so much more
> complicated than ours:
> 
>   template<typename _Tp>
>     struct remove_const
>     { typedef _Tp     type; };
> 
>   template<typename _Tp>
>     struct remove_const<_Tp const>
>     { typedef _Tp     type; };
> 
> That doesn't need to form a pointer then remove it again, so works with
> function types.

I don' think that this specialization can - according to the language - remove const qualifiers of function types, because there is no const-qualifier to remove. As far as I remember the core language makes this possible when rewriting the specialization to be one for a function type, as of core wording resolution

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#547
Comment 10 blastrock 2014-05-14 13:40:35 UTC
(In reply to Daniel Krügler from comment #9)
> I don' think that this specialization can - according to the language -
> remove const qualifiers of function types, because there is no
> const-qualifier to remove.

remove_const does not remove const from functions even in previous function of gcc and I do not expect it to do that. I expect it to give the same type, unchanged as it does with gcc < 4.9.
Comment 11 Daniel Krügler 2014-05-14 18:35:10 UTC
(In reply to pdaouadi from comment #3)
> Still, if the standard says that it is not allowed we can work around it,
> but then should I file a bug to clang?

I have done so,

http://llvm.org/bugs/show_bug.cgi?id=19742
Comment 12 Jason Merrill 2014-05-27 20:13:44 UTC
So, not a GCC bug.