PR c++/90473 - wrong code with nullptr in default argument.
authorMarek Polacek <polacek@redhat.com>
Tue, 13 Aug 2019 15:05:48 +0000 (15:05 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Tue, 13 Aug 2019 15:05:48 +0000 (15:05 +0000)
* call.c (null_ptr_cst_p): Update quote from the standard.
* decl.c (check_default_argument): Don't return nullptr when the arg
has side-effects.

* g++.dg/cpp0x/nullptr42.C: New test.

From-SVN: r274382

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nullptr42.C [new file with mode: 0644]

index 5f1dff89c0d07fabc5774d91af20c3cf30493bf5..28bc2a4cec414cd8aea9c12804c8fe42ac75deeb 100644 (file)
@@ -1,3 +1,10 @@
+2019-08-13  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/90473 - wrong code with nullptr in default argument.
+       * call.c (null_ptr_cst_p): Update quote from the standard.
+       * decl.c (check_default_argument): Don't return nullptr when the arg
+       has side-effects.
+
 2019-08-13  Marek Polacek  <polacek@redhat.com>
 
        * cp-tree.h (DECL_MUTABLE_P): Use FIELD_DECL_CHECK.
index 61334a16248b2f26302781302ab19ae9eb1bb125..01a25ad6e1e703792aade1084291282abc3485c8 100644 (file)
@@ -529,9 +529,8 @@ null_ptr_cst_p (tree t)
 
   /* [conv.ptr]
 
-     A null pointer constant is an integral constant expression
-     (_expr.const_) rvalue of integer type that evaluates to zero or
-     an rvalue of type std::nullptr_t. */
+     A null pointer constant is an integer literal ([lex.icon]) with value
+     zero or a prvalue of type std::nullptr_t.  */
   if (NULLPTR_TYPE_P (type))
     return true;
 
index b8806e4628d92e1b0b458699497b63c153a32b29..d91f25183fb5e09915f5449283f2bd694becae6d 100644 (file)
@@ -13177,7 +13177,9 @@ check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
   /* Avoid redundant -Wzero-as-null-pointer-constant warnings at
      the call sites.  */
   if (TYPE_PTR_OR_PTRMEM_P (decl_type)
-      && null_ptr_cst_p (arg))
+      && null_ptr_cst_p (arg)
+      /* Don't lose side-effects as in PR90473.  */
+      && !TREE_SIDE_EFFECTS (arg))
     return nullptr_node;
 
   /* [dcl.fct.default]
index a24386608a44ed45be7abd39ee6c6d8553dae2ad..b881498954525b6d01959825f39e06c77630064b 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-13  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/90473 - wrong code with nullptr in default argument.
+       * g++.dg/cpp0x/nullptr42.C: New test.
+
 2019-08-13  Olivier Hainque  <hainque@adacore.com>
 
        * gnat.dg/casesi.ad[bs], test_casesi.adb: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr42.C b/gcc/testsuite/g++.dg/cpp0x/nullptr42.C
new file mode 100644 (file)
index 0000000..2fb628d
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/90473 - wrong code with nullptr in default argument.
+// { dg-do run { target c++11 } }
+
+int g;
+void f() { g++; }
+
+void fn1 (void* p = (f(), nullptr)) { }
+void fn2 (int p = (f(), 0)) { }
+
+int main()
+{
+  fn1 ();
+  if (g != 1)
+    __builtin_abort ();
+  fn2 ();
+  if (g != 2)
+    __builtin_abort ();
+}