public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2] c++: side effect in nullptr_t conversion fix
@ 2024-01-11 20:34 Dmitry Drozodv
  2024-01-16 21:09 ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Drozodv @ 2024-01-11 20:34 UTC (permalink / raw)
  To: jakub; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2723 bytes --]

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);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-18 16:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-11 20:34 [PATCH v2] c++: side effect in nullptr_t conversion fix Dmitry Drozodv
2024-01-16 21:09 ` Jason Merrill
2024-01-18 16:37   ` Dmitry Drozodv

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).