[PATCH v2] c++: resolvedness of resolve_nondeduced_context result [PR126406]

Patrick Palka <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Changes in v2:
  - Outright revert r16-5967, and instead fix PR119343 more directly
    for sake of backports.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/16?

-- >8 --

In r16-5967-gbae0ed69e1862a we removed the mark_used call from
resolve_nondeduced_context under the rationale that it should be
the callers' responsiblity to do so.c

Removing this call however now means that resolve_nondeduced_context
could return a specialization whose type is not yet fully resolved
(i.e. has an uninstantiated noexcept or undeduced return type), and
callers that immediately inspect TREE_TYPE of the result (such as
standard_conversion and build_conditional_expr) now misbehave.

In light of such callers, this patch reverts r16-5967 and more
directly fixes the PR119343 bug by just propagating error_mark_node
from resolve_nondeduced_context during convert_to_void.

	PR c++/126406
	PR c++/119343

gcc/cp/ChangeLog:

	* cvt.cc (convert_to_void): Propagate error_mark_node result
	from resolve_nondeduced_context.
	* pt.cc (resolve_nondeduced_context): Revert r16-5967 change.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/cond2a.C: New test.
	* g++.dg/cpp1y/auto-fn67.C: New test.
	* g++.dg/cpp1z/noexcept-type29.C: New test.
---
 gcc/cp/cvt.cc                                |  3 ++-
 gcc/cp/pt.cc                                 |  2 ++
 gcc/testsuite/g++.dg/cpp0x/cond2a.C          | 17 +++++++++++++++++
 gcc/testsuite/g++.dg/cpp1y/auto-fn67.C       | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C | 11 +++++++++++
 5 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/cond2a.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/auto-fn67.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C

diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index a378b51a2bed..3b68b8723afb 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1573,7 +1573,8 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
     default:;
     }
   expr = resolve_nondeduced_context (expr, complain);
-  if (!mark_single_function (expr, complain))
+  if (expr == error_mark_node
+      || !mark_single_function (expr, complain))
     return error_mark_node;
 
   {
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 6a081b838e06..1d22563bc586 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25653,6 +25653,8 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
 	}
       if (good == 1)
 	{
+	  if (!mark_used (goodfn, complain) && !(complain & tf_error))
+	    return error_mark_node;
 	  expr = goodfn;
 	  if (baselink)
 	    expr = build_baselink (BASELINK_BINFO (baselink),
diff --git a/gcc/testsuite/g++.dg/cpp0x/cond2a.C b/gcc/testsuite/g++.dg/cpp0x/cond2a.C
new file mode 100644
index 000000000000..a42e198291b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/cond2a.C
@@ -0,0 +1,17 @@
+// PR c++/126406
+// { dg-do compile { target c++14 } }
+// A version of cond2.C where f has a deduced return type
+// and g is instantiated.
+
+bool b;
+
+template < class T > auto f ()
+{
+}
+
+template < class T > auto g () -> decltype (b ? f < int > : throw 0)
+{
+  return b ? f<int> : throw 0;
+}
+
+using type = decltype(g<int>());
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C
new file mode 100644
index 000000000000..20ff86459c3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C
@@ -0,0 +1,11 @@
+// PR c++/126406
+// { dg-do compile { target c++14 } }
+
+template<class T> auto g(T) { }
+static_assert(g<int>);
+
+template<class T>
+struct B {
+  static auto g(T) { }
+};
+static_assert(B<int>::g);
diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C
new file mode 100644
index 000000000000..c620b180fc83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C
@@ -0,0 +1,11 @@
+// PR c++/126406
+// { dg-do compile { target c++11 } }
+
+template<class T> void f(T) noexcept(noexcept(T())) { }
+static_assert(f<int>);
+
+template<class T>
+struct A {
+  static void f(T) noexcept(noexcept(T())) { }
+};
+static_assert(A<int>::f);
-- 
2.55.0.424.g13c7afec21
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.