c++: modules, generic lambda, constexpr if

Message ID 20250110024258.4137086-1-jason@redhat.com
State New
Headers
Series c++: modules, generic lambda, constexpr if |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jason Merrill Jan. 10, 2025, 2:42 a.m. UTC
  Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

In std/ranges/concat/1.cc we end up instantiating
concat_view::iterator::operator-, which has nested generic lambdas, where
the innermost is all constexpr if.  tsubst_lambda_expr propagates
the returns_* flags for generic lambdas since we might not substitute into
the whole function, as in this case with constexpr if.  But the module
wasn't preserving that flag, and so the importer gave a bogus "no return
statement" diagnostic.

gcc/cp/ChangeLog:

	* module.cc (trees_out::write_function_def): Write returns* flags.
	(struct post_process_data): Add returns_* flags.
	(trees_in::read_function_def): Set them.
	(module_state::read_cluster): Use them.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/constexpr-if-1_a.C: New test.
	* g++.dg/modules/constexpr-if-1_b.C: New test.
---
 gcc/cp/module.cc                              | 24 ++++++++++++++++---
 .../g++.dg/modules/constexpr-if-1_a.C         | 14 +++++++++++
 .../g++.dg/modules/constexpr-if-1_b.C         |  8 +++++++
 3 files changed, 43 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C


base-commit: fab96de044f1f023f52d43af866205d17d8895fb
  

Patch

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 5350e6c4bad..0533a2bcf2c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -2929,6 +2929,10 @@  struct post_process_data {
   tree decl;
   location_t start_locus;
   location_t end_locus;
+  bool returns_value;
+  bool returns_null;
+  bool returns_abnormally;
+  bool infinite_loop;
 };
 
 /* Tree stream reader.  Note that reading a stream doesn't mark the
@@ -12263,10 +12267,16 @@  trees_out::write_function_def (tree decl)
     {
       unsigned flags = 0;
 
+      flags |= 1 * DECL_NOT_REALLY_EXTERN (decl);
       if (f)
-	flags |= 2;
-      if (DECL_NOT_REALLY_EXTERN (decl))
-	flags |= 1;
+	{
+	  flags |= 2;
+	  /* These flags are needed in tsubst_lambda_expr.  */
+	  flags |= 4 * f->language->returns_value;
+	  flags |= 8 * f->language->returns_null;
+	  flags |= 16 * f->language->returns_abnormally;
+	  flags |= 32 * f->language->infinite_loop;
+	}
 
       u (flags);
     }
@@ -12314,6 +12324,10 @@  trees_in::read_function_def (tree decl, tree maybe_template)
     {
       pdata.start_locus = state->read_location (*this);
       pdata.end_locus = state->read_location (*this);
+      pdata.returns_value = flags & 4;
+      pdata.returns_null = flags & 8;
+      pdata.returns_abnormally = flags & 16;
+      pdata.infinite_loop = flags & 32;
     }
 
   if (get_overrun ())
@@ -16232,6 +16246,10 @@  module_state::read_cluster (unsigned snum)
       cfun->language->base.x_stmt_tree.stmts_are_full_exprs_p = 1;
       cfun->function_start_locus = pdata.start_locus;
       cfun->function_end_locus = pdata.end_locus;
+      cfun->language->returns_value = pdata.returns_value;
+      cfun->language->returns_null = pdata.returns_null;
+      cfun->language->returns_abnormally = pdata.returns_abnormally;
+      cfun->language->infinite_loop = pdata.infinite_loop;
 
       if (abstract)
 	;
diff --git a/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C b/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C
new file mode 100644
index 00000000000..80a064f4d39
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/constexpr-if-1_a.C
@@ -0,0 +1,14 @@ 
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fmodules }
+
+export module M;
+
+export
+template <class T>
+inline void f()
+{
+  []<int M>() -> int {
+    if constexpr (M > 0) { return true; }
+    else { return false; }
+  };
+}
diff --git a/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C b/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C
new file mode 100644
index 00000000000..af285da79ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/constexpr-if-1_b.C
@@ -0,0 +1,8 @@ 
+// { dg-additional-options -fmodules }
+
+import M;
+
+int main()
+{
+  f<int>();
+}