This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/69379 (ICE with PTRMEM_CST wrapped in NOP_EXPR)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]