Bug 114569 - GCC accepts forming pointer to function type which is ref qualified
Summary: GCC accepts forming pointer to function type which is ref qualified
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2024-04-03 07:02 UTC by Jason Liam
Modified: 2024-04-04 16:45 UTC (History)
4 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Liam 2024-04-03 07:02:48 UTC
In the following program `#2` is accepts by all compilers but `#1` is rejected. Shouldn't `#2` also be rejected for the same reason. https://godbolt.org/z/sMraETcbx

```
#include <type_traits> 
template <class Signature>
struct Decompose;

template <class T>
struct Decompose<void(T)> {
    using Type = T;
};

template <class T>
using FTDecay = typename Decompose<void(T)>::Type;



// static_assert(std::is_same_v<FTDecay<int()&>, int (*)() &>);  //#1: all rejects this as expected 
 FTDecay<int()&> x{};                                            //#2: all accepts this why? 
```
Comment 1 Marek Polacek 2024-04-03 14:25:25 UTC
[dcl.fct]/10:
A function type with a cv-qualifier-seq or a ref-qualifier shall appear only as: 
-- [...]
-- the type-id of a template-argument for a type-parameter

So the code should compile.
Comment 2 Jason Liam 2024-04-03 15:16:31 UTC
(In reply to Marek Polacek from comment #1)
> So the code should compile.

But https://timsong-cpp.github.io/cppwp/n4950/dcl.ptr#4.sentence-2 says:

> [Note 1: [...] Forming a function pointer type is ill-formed if the function type has cv-qualifiers or a ref-qualifier; see [dcl.fct]. [...]]

And since `FTDecay<int()&>` is `int (*)() &`, this should be ill-formed?
Comment 3 Jens Maurer 2024-04-04 06:58:48 UTC
Note that the ref-qualified function type is not directly an argument for a template type parameter (which would be allowed), but it's a function parameter type inside a function declarator.  And those do decay to (possibly ill-formed) pointers.