Hello,

You are absolutely right, we can't throw all side-effects away.
Example:
```c++
auto __attribute__ ((noinline)) bar()
{
   volatile int* b = (int *)0xff;
   *b = 10;
   volatile auto n = nullptr;
   return n;                                   // Problem (1)
}

int* foo_2()
{
  volatile auto a = bar();              // Problem (2)
  return a;
}
```
There are 2 additional places, where std::nullptr_t causes side effects.
(1)
nullptr_t identical conversion produces:
        mov     QWORD PTR [rsp-8], 0
        mov     rax, QWORD PTR [rsp-8]     // load n
        ret

(2)
Initialization by not constant expression:
        call    bar()
        mov     QWORD PTR [rsp+8], rax
        mov     rax, QWORD PTR [rsp+8]
        xor     eax, eax


---

diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index cbed847b343..24c1ceb4404 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -218,8 +218,11 @@ cp_convert_to_pointer (tree type, tree expr, bool
dofold,
                  ? build_int_cst_type (type, -1)
                  : build_int_cst (type, 0));

-      return (TREE_SIDE_EFFECTS (expr)
-             ? build2 (COMPOUND_EXPR, type, expr, val) : val);
+      /* C++ [conv.lval]p3:
+        If T is cv std::nullptr_t, the result is a null pointer constant.
*/
+      return ((TREE_SIDE_EFFECTS (expr) && !CONVERT_EXPR_P (expr))
+              ? build2 (COMPOUND_EXPR, type, expr, val)
+              : val);
     }
   else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
     {
@@ -743,8 +746,9 @@ ocp_convert (tree type, tree expr, int convtype, int
flags,
     {
       if (complain & tf_warning)
        maybe_warn_zero_as_null_pointer_constant (e, loc);
-
-      if (!TREE_SIDE_EFFECTS (e))
+      /* C++ [conv.lval]p3:
+        Convert expr from nullptr to nullptr doesn't have side effect. */
+      if (!TREE_SIDE_EFFECTS (e) || CONVERT_EXPR_P (expr))
        return nullptr_node;
     }

diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index ac0fefa24f2..9c7866d319f 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -770,6 +770,15 @@ split_nonconstant_init (tree dest, tree init)
           && array_of_runtime_bound_p (TREE_TYPE (dest)))
     code = build_vec_init (dest, NULL_TREE, init, /*value-init*/false,
                           /*from array*/1, tf_warning_or_error);
+  else if (TREE_CODE (TREE_TYPE(init)) == NULLPTR_TYPE)
+    {
+      /* C++ [conv.lval]p3:
+        If T is cv std::nullptr_t, the result is a null pointer constant.
*/
+      tree val = build_int_cst(TREE_TYPE(dest), 0);
+      tree ie = cp_build_init_expr(dest, val);
+      // remain expr with side effect
+      code = add_stmt_to_compound(init, ie);
+    }
   else
     code = cp_build_init_expr (dest, init);

Reply via email to