Where does the rule in the standard specify that a function with a trailing-return-type whose return type contains a placeholder type should be `auto`

Viewed 94
auto* fun()->int*{}
int main(){
}

This snippet is rejected by both Clang and GCC, and they report an error, which is

'fun' function with trailing return type has 'auto*' as its type rather than plain 'auto'

However, I haven't found any rule that forbids this usage in the standard. The only relevant rule that I feel correspond is the following:

In a declaration T D where D has the form

 D1 ( parameter-declaration-clause ) cv-qualifier-seq opt
    ref-qualifier opt noexcept-specifier opt attribute-specifier-seq opt trailing-return-type

and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”, T shall be the single type-specifier auto.

However, according to dcl.meaning#3, which says:

Thus, a declaration of a particular identifier has the form

T D

where T is of the form attribute-specifier-seqopt decl-specifier-seq and D is a declarator.

Hence, back to this example, T is auto and the declarator is *fun()->int*. So, T here is a single type-specifier auto, the declaration does not violate any rule. Why do GCC and Clang both reject the valid code? If I miss the rule that forbids this usage in the standard, what's the rule?

2 Answers

It's the grammar. This was core issue 681.

declarator:
  ptr-declarator
  noptr-declarator parameters-and-qualifiers trailing-return-type

ptr-declarator:
  noptr-declarator
  ptr-operator ptr-declarator

noptr-declarator:
  declarator-id attribute-specifier-seq_opt
  noptr-declarator parameters-and-qualifiers
  noptr-declarator [ constant-expression_opt ] attribute-specifier-seq_opt
  ( ptr-declarator )

*f () -> whatever is not a valid declarator; the grammar disallows a ptr-declarator at that position. (It follows that it is unsurprising that the rules for interpreting declarators don't provide for this occasion - as discussed in the comments.)

[dcl.fct]/2 states:

In a declaration T D where D has the form

D1 ( parameter-declaration-clause ) cv-qualifier-seq-opt 
  ref-qualifier-opt noexcept-specifier-opt attribute-specifier-seq-opt trailing-return-type

and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”, T shall be the single type-specifier auto.[...]

emphasis mine

which is where it is required to be auto.

Related