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.
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.
In fact, icc, clang, and SolarisStudio appear to accept pointers to qualified function types?!?
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?
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.
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.
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.
(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.
(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
(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
(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.
(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
So, not a GCC bug.