https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111352
Egas Ribeiro <egas.g.ribeiro at tecnico dot ulisboa.pt> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |egas.g.ribeiro at tecnico dot
ulis
| |boa.pt
--- Comment #5 from Egas Ribeiro <egas.g.ribeiro at tecnico dot ulisboa.pt> ---
I attempted a fix by adding cp_parser_simulate_error check before the error in
cp_parser_parameter_declaration_clause (see patch below). This fixes the
original test case, but causes a regression in g++.dg/cpp23/auto-fncast15.C.
The issue is that my fix prevents the error from being emitted during tentative
parsing, but in auto-fncast15.C, the code like A b4(auto(a), auto(a2)) should
error because it's attempting an implicit function template declaration at
block scope (which isn't allowed). After my change, GCC incorrectly treats this
as a constructor call instead of recognizing it as an invalid function
declaration.
This appears to conflict with the fix for PR112482 (commit 1ae71269), which
moved the auto parameter check to cp_parser_parameter_declaration_clause
specifically to handle these block-scope cases. The challenge is distinguishing
between:
Valid: AA aa(Constructor([&](auto& p) {...})) - constructor with lambda
Invalid: A b4(auto(a), auto(a2)) - implicit function template at block scope
I need to understand why the tentative parse path is treating b4 differently
after my change. It seems that by suppressing the error during tentative
parsing, GCC is recognizing this as a constructor call rather than as an
invalid function declaration.
Hope this helps someone.
---
PR c++/111352
gcc/cp/ChangeLog:
* parser.cc (cp_parser_parameter_declaration_clause): Suppress
auto parameter error during tentative parsing.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/lambda-pr111352.C: New test.
---
gcc/cp/parser.cc | 5 +-
gcc/testsuite/g++.dg/cpp1z/lambda-pr111352.C | 50 ++++++++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1z/lambda-pr111352.C
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 9280632d47b..e4bd35e0def 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -26820,8 +26820,9 @@ cp_parser_parameter_declaration_clause (cp_parser*
parser,
for (tree p = parameters; p; p = TREE_CHAIN (p))
if (type_uses_auto (TREE_TYPE (TREE_VALUE (p))))
{
- error_at (location_of (TREE_VALUE (p)),
- "%<auto%> parameter not permitted in this context");
+ if (!cp_parser_simulate_error (parser))
+ error_at (location_of (TREE_VALUE (p)),
+ "%<auto%> parameter not permitted in this context");
TREE_TYPE (TREE_VALUE (p)) = error_mark_node;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/lambda-pr111352.C
b/gcc/testsuite/g++.dg/cpp1z/lambda-pr111352.C
new file mode 100644
index 00000000000..46832c33697
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/lambda-pr111352.C
@@ -0,0 +1,50 @@
+// PR c++/111352
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+ int x;
+};
+
+template <typename L> struct Constructor
+{
+ const L& lambda;
+ Constructor(const L& lambda) :
+ lambda(lambda)
+ {
+ }
+ operator A () const
+ {
+ A out;
+ lambda(out);
+ return out;
+ }
+};
+
+
+struct AA
+{
+ int x{0};
+
+ AA()
+ {
+ }
+
+ AA(A op) :
+ x(op.x)
+ {
+ }
+};
+
+template <typename L> Constructor<L>
+make_constructor(const L& lambda)
+{
+ return Constructor<L>(lambda);
+}
+
+int main()
+{
+ AA aa (make_constructor([&](auto& p) { p.x = 1; }));
+ AA bb = AA( make_constructor([&](auto& p) { p.x = 1; }));
+}
+
--
2.51.0