From 1cf424ec03baf6f2e82003b338e8d1327fc3eaac Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 21 Jun 2023 01:58:33 -0700 Subject: [PATCH 1/2] P2915R0 Proposed resolution for CWG1223 Editorial notes: - [dcl.ambig.res] Use "is to be considered a" instead of "is" to avoid redefining the grammar production /type-id/. - [stmt.ambig] Likewise, don't use \grammarterm "declaration" in "is a declaration" to avoid redefining /declaration/. - [stmt.ambig] Reword comment in example for consistency. --- source/declarations.tex | 19 +++++++++++++++++++ source/statements.tex | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index 0b70486f08..04fa7dcd69 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 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..608f577935 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 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 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|)} From 9b9ebcc9c3135cc349381b2ce7fa9b426988831f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 29 Jun 2023 15:55:02 -0700 Subject: [PATCH 2/2] [dcl.ambig.res][stmt.ambig] Change "is" to "is considered". This avoids suggesting that any \grammarterms are being (re)defined. --- source/declarations.tex | 2 +- source/statements.tex | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 04fa7dcd69..e244170c6b 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -2413,7 +2413,7 @@ whose outermost \grammarterm{abstract-declarator} would match the grammar of an \grammarterm{abstract-declarator} with a \grammarterm{trailing-return-type} -is a \grammarterm{type-id} only if it starts with \keyword{auto}. +is considered a \grammarterm{type-id} only if it starts with \keyword{auto}. \begin{example} \begin{codeblock} template struct X {}; diff --git a/source/statements.tex b/source/statements.tex index 608f577935..4f0c773c51 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -1081,7 +1081,7 @@ 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 @@ -1169,7 +1169,7 @@ A syntactically ambiguous statement that can syntactically be a \grammarterm{declaration} with an outermost \grammarterm{declarator} with a \grammarterm{trailing-return-type} -is a \grammarterm{declaration} only if it starts with \keyword{auto}. +is considered a \grammarterm{declaration} only if it starts with \keyword{auto}. \begin{example} \begin{codeblock} struct M;