This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/69379 (ICE with PTRMEM_CST wrapped in NOP_EXPR)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Thu, 21 Jan 2016 19:25:32 +0100
- Subject: C++ PATCH for c++/69379 (ICE with PTRMEM_CST wrapped in NOP_EXPR)
- Authentication-results: sourceware.org; auth=none
The problem in this PR is that we have a PTRMEM_CST wrapped in NOP_EXPR
and fold_convert can't digest that.
For the unreduced test in the PR, this occurs since rev 230508: we force
a NOP_EXPR when converting to the same type in build_static_cast_1:
if (result == expr && SCALAR_TYPE_P (type))
/* Leave some record of the cast. */
result = build_nop (type, expr);
For the reduced test in the PR, this happens since the C++ delayed folding
merge, and we wrap a PTRMEM_CST in NOP_EXPR in build_reinterpret_cast:
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
return build_nop (type, expr);
This patch <https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00679.html> prevented
cp_fold_convert to wrap a PTRMEM_CST in NOP_EXPR, but in this case
cp_fold_convert gets a PTRMEM_CST already wrapped in NOP_EXPR. I think we can
fix this by extending the fix to also handle nested PTRMEM_CSTs. I've verified
that this fixes the ICE with the unreduced testcase too.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2016-01-21 Marek Polacek <polacek@redhat.com>
PR c++/69379
* cvt.c (cp_fold_convert): Handle PTRMEM_CSTs wrapped in NOP_EXPRs.
* g++.dg/pr69379.C: New test.
diff --git gcc/cp/cvt.c gcc/cp/cvt.c
index f381f9b..667307a 100644
--- gcc/cp/cvt.c
+++ gcc/cp/cvt.c
@@ -592,12 +592,14 @@ tree
cp_fold_convert (tree type, tree expr)
{
tree conv;
+ tree sexpr = tree_strip_nop_conversions (expr);
+
if (TREE_TYPE (expr) == type)
conv = expr;
- else if (TREE_CODE (expr) == PTRMEM_CST)
+ else if (TREE_CODE (sexpr) == PTRMEM_CST)
{
/* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */
- conv = copy_node (expr);
+ conv = copy_node (sexpr);
TREE_TYPE (conv) = type;
}
else
diff --git gcc/testsuite/g++.dg/pr69379.C gcc/testsuite/g++.dg/pr69379.C
index e69de29..249ad00 100644
--- gcc/testsuite/g++.dg/pr69379.C
+++ gcc/testsuite/g++.dg/pr69379.C
@@ -0,0 +1,20 @@
+// PR c++/69379
+// { dg-do compile }
+// { dg-options "-Wformat" }
+
+typedef int T;
+class A {
+public:
+ template <class D> A(const char *, D);
+ template <class Fn, class A1, class A2>
+ void m_fn1(const char *, Fn, A1 const &, A2);
+};
+struct Dict {
+ void m_fn2();
+};
+void fn1() {
+ A a("", "");
+ typedef void *Get;
+ typedef void (Dict::*d)(T);
+ a.m_fn1("", Get(), d(&Dict::m_fn2), "");
+}
Marek