diff --git a/source/declarations.tex b/source/declarations.tex index 0b70486f08..e244170c6b 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -2371,6 +2371,11 @@ such as the potential parameter declaration, that could possibly be a declaration to be a declaration. +However, a construct that can syntactically be a \grammarterm{declaration} +whose outermost \grammarterm{declarator} +would match the grammar of a \grammarterm{declarator} +with a \grammarterm{trailing-return-type} +is a declaration only if it starts with \keyword{auto}. \begin{note} A declaration can be explicitly disambiguated by adding parentheses around the argument. @@ -2382,6 +2387,7 @@ struct S { S(int); }; +typedef struct BB { int C[2]; } *B, C; void foo(double a) { S w(int(a)); // function declaration @@ -2389,6 +2395,8 @@ S y((int(a))); // object declaration S y((int)a); // object declaration S z = int(a); // object declaration + S a(B()->C); // object declaration + S b(auto()->C); // function declaration } \end{codeblock} \end{example} @@ -2401,6 +2409,11 @@ \grammarterm{type-id} in its syntactic context shall be considered a \grammarterm{type-id}. +However, a construct that can syntactically be a \grammarterm{type-id} +whose outermost \grammarterm{abstract-declarator} +would match the grammar of an \grammarterm{abstract-declarator} +with a \grammarterm{trailing-return-type} +is considered a \grammarterm{type-id} only if it starts with \keyword{auto}. \begin{example} \begin{codeblock} template struct X {}; @@ -2419,6 +2432,12 @@ (int(a))+1; // expression (int(unsigned(a)))+1; // type-id (ill-formed) } + +typedef struct BB { int C[2]; } *B, C; +void g() { + sizeof(B()->C[1]); // OK, \tcode{\keyword{sizeof}(}expression\tcode{)} + sizeof(auto()->C[1]); // error: \keyword{sizeof} of a function returning an array +} \end{codeblock} \end{example} diff --git a/source/statements.tex b/source/statements.tex index aa9ae2bbbf..4f0c773c51 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -1081,7 +1081,8 @@ conversion\iref{expr.type.conv} as its leftmost subexpression can be indistinguishable from a \grammarterm{declaration} where the first \grammarterm{declarator} starts with a \tcode{(}. In those cases the -\grammarterm{statement} is a \grammarterm{declaration}. +\grammarterm{statement} is considered a \grammarterm{declaration}, +except as specified below. \pnum \begin{note} @@ -1163,4 +1164,35 @@ } \end{codeblock} \end{example} + +\pnum +A syntactically ambiguous statement that can syntactically be +a \grammarterm{declaration} with an outermost \grammarterm{declarator} +with a \grammarterm{trailing-return-type} +is considered a \grammarterm{declaration} only if it starts with \keyword{auto}. +\begin{example} +\begin{codeblock} +struct M; +struct S { + S* operator()(); + int N; + int M; + + void mem(S s) { + auto(s)()->M; // expression, \tcode{S::M} hides \tcode{::M} + } +}; + +void f(S s) { + { + auto(s)()->N; // expression + auto(s)()->M; // function declaration + } + { + S(s)()->N; // expression + S(s)()->M; // expression + } +} +\end{codeblock} +\end{example} \indextext{statement|)}