re PR c++/80095 (ICE with this pointer in NSDMI)
authorMarek Polacek <polacek@redhat.com>
Fri, 7 Apr 2017 18:09:55 +0000 (18:09 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 7 Apr 2017 18:09:55 +0000 (18:09 +0000)
PR c++/80095
* call.c (build_over_call): Don't check cxx_dialect.
* cp-gimplify.c (cp_gimplify_init_expr): Don't check cxx_dialect nor
whether SUB is a CONSTRUCTOR.
* init.c (build_new_1): Don't check cxx_dialect.
* tree.c (replace_placeholders): Add a function comment.  Return if
not in C++14, or if the object isn't a (member of a) class.
* typeck2.c (store_init_value): Don't check cxx_dialect nor whether
TYPE is CLASS_TYPE_P.

* g++.dg/cpp1y/nsdmi-aggr8.C: New test.

From-SVN: r246772

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-gimplify.c
gcc/cp/init.c
gcc/cp/tree.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C [new file with mode: 0644]

index 5ffd1b74490302ecaef73833704ac82f2c1a386c..a31d114374f29aea0b4442c33e6634e22b76eada 100644 (file)
@@ -3,6 +3,16 @@
        PR sanitizer/80348
        * typeck.c (cp_build_binary_op): Convert COP[01] to ORIG_TYPE.
 
+       PR c++/80095
+       * call.c (build_over_call): Don't check cxx_dialect.
+       * cp-gimplify.c (cp_gimplify_init_expr): Don't check cxx_dialect nor
+       whether SUB is a CONSTRUCTOR.
+       * init.c (build_new_1): Don't check cxx_dialect.
+       * tree.c (replace_placeholders): Add a function comment.  Return if
+       not in C++14, or if the object isn't a (member of a) class.
+       * typeck2.c (store_init_value): Don't check cxx_dialect nor whether
+       TYPE is CLASS_TYPE_P.
+
 2017-04-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80309
index 803fbd4197e9ab1b030717d2a3505cf1690106dc..c15b8e46f34b93bb1d16ebb68e35e0e1759b6c7f 100644 (file)
@@ -8047,9 +8047,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        {
          arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
-         if (cxx_dialect >= cxx14)
-           /* Handle NSDMI that refer to the object being initialized.  */
-           replace_placeholders (arg, to);
+         /* Handle NSDMI that refer to the object being initialized.  */
+         replace_placeholders (arg, to);
        }
       else
        {
index 6e49daf84997c8aafb46f989f0df04cab8ac96c1..f2c52963a9fceb1adbaf744ad715474cbd0dc7a4 100644 (file)
@@ -496,9 +496,8 @@ cp_gimplify_init_expr (tree *expr_p)
            TREE_TYPE (from) = void_type_node;
        }
 
-      if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR)
-       /* Handle aggregate NSDMI.  */
-       replace_placeholders (sub, to);
+      /* Handle aggregate NSDMI.  */
+      replace_placeholders (sub, to);
 
       if (t == sub)
        break;
index 2015205efd66ff01871076a84318c2da57652b16..bfa902050cbbed0b03168a66832bcb777e2f2f7d 100644 (file)
@@ -3373,8 +3373,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
             object being initialized, replace them now and don't try to
             preevaluate.  */
          bool had_placeholder = false;
-         if (cxx_dialect >= cxx14
-             && !processing_template_decl
+         if (!processing_template_decl
              && TREE_CODE (init_expr) == INIT_EXPR)
            TREE_OPERAND (init_expr, 1)
              = replace_placeholders (TREE_OPERAND (init_expr, 1),
index 2757af6691d5baee0bfc69d3be025ed1f8e8afed..99391352e3a2072422258d1b6d04a540267dd1d1 100644 (file)
@@ -2813,9 +2813,23 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
   return NULL_TREE;
 }
 
+/* Replace PLACEHOLDER_EXPRs in EXP with object OBJ.  SEEN_P is set if
+   a PLACEHOLDER_EXPR has been encountered.  */
+
 tree
 replace_placeholders (tree exp, tree obj, bool *seen_p)
 {
+  /* This is only relevant for C++14.  */
+  if (cxx_dialect < cxx14)
+    return exp;
+
+  /* If the object isn't a (member of a) class, do nothing.  */
+  tree op0 = obj;
+  while (TREE_CODE (op0) == COMPONENT_REF)
+    op0 = TREE_OPERAND (op0, 0);
+  if (!CLASS_TYPE_P (strip_array_types (TREE_TYPE (op0))))
+    return exp;
+
   tree *tp = &exp;
   replace_placeholders_t data = { obj, false };
   if (TREE_CODE (exp) == TARGET_EXPR)
index d1a393059a49bb12a3cdac0994e62258bac2001d..1f0eb454754bcf55a4250e11158f36b94a8c2efd 100644 (file)
@@ -840,9 +840,8 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
     }
   value = cp_fully_fold (value);
 
-  if (cxx_dialect >= cxx14 && CLASS_TYPE_P (strip_array_types (type)))
-    /* Handle aggregate NSDMI in non-constant initializers, too.  */
-    value = replace_placeholders (value, decl);
+  /* Handle aggregate NSDMI in non-constant initializers, too.  */
+  value = replace_placeholders (value, decl);
 
   /* DECL may change value; purge caches.  */
   clear_cv_and_fold_caches ();
index fbaef7a35aeabba170aecbe9b26dd40ed688676e..6150f74622961865054cb4b4201568da34a5c613 100644 (file)
@@ -3,6 +3,9 @@
        PR sanitizer/80348
        * g++.dg/ubsan/div-by-zero-2.C: New test.
 
+       PR c++/80095
+       * g++.dg/cpp1y/nsdmi-aggr8.C: New test.
+
 2017-04-07  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/70478
diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C
new file mode 100644 (file)
index 0000000..8c99ffb
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/80095
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+  void* p = this;
+};
+
+void
+foo ()
+{
+  const A& a = A{};
+  A&& a2 = A{};
+  const A& a3{};
+  A&& a4{};
+}