]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix auto return type deduction with expansion statements [PR121583]
authorJakub Jelinek <jakub@redhat.com>
Thu, 28 Aug 2025 08:51:09 +0000 (10:51 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 28 Aug 2025 08:51:09 +0000 (10:51 +0200)
The following testcase ICEs during expansion, because cfun->returns_struct
wasn't cleared, despite auto being deduced to int.

The problem is that check_return_type -> apply_deduced_return_type
is called when parsing the expansion stmt body, at that time
processing_template_decl is non-zero and apply_deduced_return_type
in that case doesn't do the
     if (function *fun = DECL_STRUCT_FUNCTION (fco))
       {
         bool aggr = aggregate_value_p (result, fco);
 #ifdef PCC_STATIC_STRUCT_RETURN
         fun->returns_pcc_struct = aggr;
 #endif
         fun->returns_struct = aggr;
       }
My assumption is that !processing_template_decl in that case
is used in the sense "the fco function is not a function template",
for function templates no reason to bother with fun->returns*struct,
nothing will care about that.
When returning a type dependent expression in the expansion stmt
body, apply_deduced_return_type just won't be called during parsing,
but when instantiating the body and all will be fine.  But when
returning a non-type-dependent expression, while check_return_type
will be called again during instantiation of the body, as the return
type is no longer auto in that case apply_deduced_return_type will not
be called again and so nothing will fix up fun->returns*struct.

The following patch fixes that by using !uses_template_parms (fco)
check instead of !processing_template_decl.

2025-08-28  Jakub Jelinek  <jakub@redhat.com>

PR c++/121583
* semantics.cc (apply_deduced_return_type): Adjust
fun->returns*_struct when !uses_template_parms (fco) instead of
when !processing_template_decl.

* g++.dg/cpp26/expansion-stmt23.C: New test.
* g++.dg/cpp26/expansion-stmt24.C: New test.

gcc/cp/semantics.cc
gcc/testsuite/g++.dg/cpp26/expansion-stmt23.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/expansion-stmt24.C [new file with mode: 0644]

index 26709c7a33bff97b5e56141dddc52895dcca1891..58e6f9461942446e618085428b033dd0a4218585 100644 (file)
@@ -14213,7 +14213,7 @@ apply_deduced_return_type (tree fco, tree return_type)
                                result);
   DECL_RESULT (fco) = result;
 
-  if (!processing_template_decl)
+  if (!uses_template_parms (fco))
     if (function *fun = DECL_STRUCT_FUNCTION (fco))
       {
        bool aggr = aggregate_value_p (result, fco);
diff --git a/gcc/testsuite/g++.dg/cpp26/expansion-stmt23.C b/gcc/testsuite/g++.dg/cpp26/expansion-stmt23.C
new file mode 100644 (file)
index 0000000..32eef41
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/121583
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+auto
+foo ()
+{
+  template for (int i : { 0 })         // { dg-warning "'template for' only available with" "" { target c++23_down } }
+    return i;
+}
+
+auto
+bar ()
+{
+  template for (auto i : { 0 })                // { dg-warning "'template for' only available with" "" { target c++23_down } }
+    return i;
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/expansion-stmt24.C b/gcc/testsuite/g++.dg/cpp26/expansion-stmt24.C
new file mode 100644 (file)
index 0000000..8a1961e
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/121583
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+auto
+foo ()
+{
+  template for (auto i : { 0, 1, 2LL })                // { dg-warning "'template for' only available with" "" { target c++23_down } }
+    return i;                                  // { dg-error "inconsistent deduction for auto return type: 'int' and then 'long long int'" }
+}