On 2/10/21 10:05 AM, Jakub Jelinek wrote:
On Tue, Feb 09, 2021 at 04:08:03PM -0500, Jason Merrill via Gcc-patches wrote:
They are not in the symtab from the C++ FE. And we don't allow those VAR_DECLs
or their
addresses to leak into the IL anyway.
But, they are TREE_STATIC because pretending they are automatic didn't
really work (e.g. address of automatic variables is not a constant expression).
The generic folding code uses maybe_nonzero_address predicate which
apprently creates a symtab entry for them but as nothing uses them they
won't be emitted.
Ah.
If we wanted to avoid that, we'd need to either add some generic VAR_DECL
bit for those vars or add a target hook that would return true for them and
then handle them in the middle-end.
I'm surprised that nonzero_address has such a limited set of things it will
actually believe have non-zero addresses with
-fno-delete-null-pointer-checks. But it seems that we should be able to
arrange to satisfy
if (definition && !DECL_EXTERNAL (decl)
since these "variables" are indeed defined within the current translation
unit.
Doing that seems to work and as added benefit it fixes another PR that has
been filed recently. I need to create the varpool node explicitly and call
a method that sets the definition member in there, but I can also unregister
those varpool nodes at the end of constexpr processing, as the processing
ensured they don't leak outside of the processing.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2021-02-10 Jakub Jelinek <ja...@redhat.com>
PR c++/98988
PR c++/99031
* constexpr.c: Include cgraph.h.
(cxx_eval_call_expression): Call varpool_node::finalize_decl on
heap artificial vars.
(cxx_eval_outermost_constant_expr): Remove varpool nodes for
heap artificial vars.
* g++.dg/cpp2a/constexpr-new16.C: New test.
* g++.dg/cpp2a/constexpr-new17.C: New test.
--- gcc/cp/constexpr.c.jj 2021-02-09 10:05:28.820833601 +0100
+++ gcc/cp/constexpr.c 2021-02-10 11:31:16.567984809 +0100
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.
#include "timevar.h"
#include "fold-const-call.h"
#include "stor-layout.h"
+#include "cgraph.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -2340,6 +2341,7 @@ cxx_eval_call_expression (const constexp
type);
DECL_ARTIFICIAL (var) = 1;
TREE_STATIC (var) = 1;
+ varpool_node::finalize_decl (var);
Please add a comment that this is for nonzero_address. OK with that change.
ctx->global->heap_vars.safe_push (var);
ctx->global->values.put (var, NULL_TREE);
return fold_convert (ptr_type_node, build_address (var));
@@ -7199,15 +7201,18 @@ cxx_eval_outermost_constant_expr (tree t
non_constant_p = true;
}
FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
- if (DECL_NAME (heap_var) != heap_deleted_identifier)
- {
- if (!allow_non_constant && !non_constant_p)
- error_at (DECL_SOURCE_LOCATION (heap_var),
- "%qE is not a constant expression because allocated "
- "storage has not been deallocated", t);
- r = t;
- non_constant_p = true;
- }
+ {
+ if (DECL_NAME (heap_var) != heap_deleted_identifier)
+ {
+ if (!allow_non_constant && !non_constant_p)
+ error_at (DECL_SOURCE_LOCATION (heap_var),
+ "%qE is not a constant expression because allocated "
+ "storage has not been deallocated", t);
+ r = t;
+ non_constant_p = true;
+ }
+ varpool_node::get (heap_var)->remove ();
+ }
}
/* Check that immediate invocation does not return an expression referencing
--- gcc/testsuite/g++.dg/cpp2a/constexpr-new16.C.jj 2021-02-10
11:11:00.117658382 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-new16.C 2021-02-10
11:11:00.117658382 +0100
@@ -0,0 +1,13 @@
+// PR c++/98988
+// { dg-do compile { target c++20 } }
+// { dg-options "-fno-delete-null-pointer-checks" }
+
+constexpr bool
+foo ()
+{
+ auto ptr = new int();
+ delete ptr;
+ return true;
+}
+
+static_assert (foo ());
--- gcc/testsuite/g++.dg/cpp2a/constexpr-new17.C.jj 2021-02-10
13:04:17.947606440 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-new17.C 2021-02-10
13:04:06.417738050 +0100
@@ -0,0 +1,15 @@
+// PR c++/99031
+// { dg-do compile { target c++20 } }
+
+constexpr bool
+foo ()
+{
+ auto a = new int;
+ auto b = new int;
+ bool r = a == b;
+ delete b;
+ delete a;
+ return r;
+}
+
+static_assert (!foo ());
Jakub