[PATCH] c++: ICE w/ maybe_warn_nodiscard on non-dep call [PR123495, PR126860]

Patrick Palka <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk? It's a checking-only ICE so no big need to backport,
maybe to 16 at most.

-- >8 --

Another latent issue uncovered by the NON_DEPENDENT_EXPR removal.
cp_get_fndecl_from_callee, called from maybe_warn_nodiscard, tries to
fold the templated callee via constant evaluation, but constant
evaluation expects non-templated trees.  So use fold_non_dependent_expr
which instantiates templated trees beforehand.

	PR c++/123495
	PR c++/126860

gcc/cp/ChangeLog:

	* cvt.cc (cp_get_fndecl_from_callee): Use fold_non_dependent_expr
	instead of maybe_constant_init.

gcc/testsuite/ChangeLog:

	* g++.dg/template/non-dependent36.C: New test.
	* g++.dg/template/non-dependent37.C: New test.
---
 gcc/cp/cvt.cc                                   | 2 +-
 gcc/testsuite/g++.dg/template/non-dependent36.C | 4 ++++
 gcc/testsuite/g++.dg/template/non-dependent37.C | 9 +++++++++
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/template/non-dependent36.C
 create mode 100644 gcc/testsuite/g++.dg/template/non-dependent37.C

diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index a378b51a2bed..33d528b3c324 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1069,7 +1069,7 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */)
   if (type == NULL_TREE || !INDIRECT_TYPE_P (type))
     return NULL_TREE;
   if (fold)
-    fn = maybe_constant_init (fn);
+    fn = fold_non_dependent_expr (fn);
   STRIP_NOPS (fn);
   if (TREE_CODE (fn) == ADDR_EXPR
       || TREE_CODE (fn) == FDESC_EXPR)
diff --git a/gcc/testsuite/g++.dg/template/non-dependent36.C b/gcc/testsuite/g++.dg/template/non-dependent36.C
new file mode 100644
index 000000000000..a4bf06974028
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent36.C
@@ -0,0 +1,4 @@
+// PR c++/123495
+
+template <int N>
+void foo () { ((int (*) ()) 0) (); }
diff --git a/gcc/testsuite/g++.dg/template/non-dependent37.C b/gcc/testsuite/g++.dg/template/non-dependent37.C
new file mode 100644
index 000000000000..ad58cf6f10ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent37.C
@@ -0,0 +1,9 @@
+// PR c++/126860
+
+struct A {
+  int (*foo)();
+};
+
+template <typename T> struct S : public A {
+  void bar() { A::foo(); }
+};
-- 
2.55.0.559.g11c6700f10
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.