In this testcase, the only returns are inside a constexpr if, and when
we're partially instantiating a generic lambda we don't mess with a
constexpr if with a dependent condition, so we don't see the returns.
Fixed by copying the relevant flags from the uninstantiated lambda.

Tested x86_64-pc-linux-gnu, applying to trunk and 8.
commit 788c94f8dc670e61c97654d3c42a0af4356ca88d
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu May 24 10:50:08 2018 -0400

            PR c++/85842 - -Wreturn-type, constexpr if and generic lambda.
    
            * pt.c (tsubst_lambda_expr): Copy current_function_returns_* to
            generic lambda.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d1181055af4..01a3ad92439 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17636,6 +17636,17 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
       register_parameter_specializations (oldfn, fn);
 
+      if (oldtmpl)
+	{
+	  /* We might not partially instantiate some parts of the function, so
+	     copy these flags from the original template.  */
+	  language_function *ol = DECL_STRUCT_FUNCTION (oldfn)->language;
+	  current_function_returns_value = ol->returns_value;
+	  current_function_returns_null = ol->returns_null;
+	  current_function_returns_abnormally = ol->returns_abnormally;
+	  current_function_infinite_loop = ol->infinite_loop;
+	}
+
       tsubst_expr (DECL_SAVED_TREE (oldfn), args, complain, r,
 		   /*constexpr*/false);
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if23.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if23.C
new file mode 100644
index 00000000000..8e31db3e863
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if23.C
@@ -0,0 +1,13 @@
+// PR c++/85842
+// { dg-additional-options -std=c++17 }
+
+template<class T>
+auto f = [](auto&& arg) -> T* {
+    if constexpr (sizeof(arg) == 1) {
+        return nullptr;
+    } else {
+        return static_cast<T*>(&arg);
+    }
+};
+
+auto p = f<int>(0);

Reply via email to