aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-07-13 17:48:05 -0400
committerJason Merrill <jason@redhat.com>2023-07-17 17:19:30 -0400
commitc7ac1de5f5c561b2d90c084a638c232d322d54e6 (patch)
treed5b323908cf927886e5536cbcd58ccae0dc1224a /gcc/cp/constexpr.cc
parentc5e9927b95debc692374a2aede21856eb94217ae (diff)
downloadgcc-c7ac1de5f5c561b2d90c084a638c232d322d54e6.zip
gcc-c7ac1de5f5c561b2d90c084a638c232d322d54e6.tar.gz
gcc-c7ac1de5f5c561b2d90c084a638c232d322d54e6.tar.bz2
c++: only cache constexpr calls that are constant exprs
In reviewing Nathaniel's patch for PR70331, it occurred to me that instead of looking for various specific problematic things in the result of a constexpr call to decide whether to cache it, we should use reduced_constant_expression_p. The change to that function is to avoid crashing on uninitialized objects of non-class type. In a trial version of this patch I checked to see what cases this stopped caching; most were instances of partially-initialized return values, which seem fine to not cache. Some were returning pointers to expiring local variables, which we definitely want not to cache. And one was bit-cast3.C, which will be handled in a follow-up patch. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Only cache reduced_constant_expression_p results. (reduced_constant_expression_p): Handle CONSTRUCTOR of scalar type. (cxx_eval_constant_expression): Fold vectors here. (cxx_eval_bare_aggregate): Not here.
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc17
1 files changed, 9 insertions, 8 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index c6f323e..9d85c3b 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3033,7 +3033,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
else
{
- bool cacheable = true;
+ bool cacheable = !!entry;
if (result && result != error_mark_node)
/* OK */;
else if (!DECL_SAVED_TREE (fun))
@@ -3185,7 +3185,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
for the constexpr evaluation and should not be cached.
It is fine if the call allocates something and deallocates it
too. */
- if (entry
+ if (cacheable
&& (save_heap_alloc_count != ctx->global->heap_vars.length ()
|| (save_heap_dealloc_count
!= ctx->global->heap_dealloc_count)))
@@ -3204,10 +3204,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
cacheable = false;
break;
}
- /* Also don't cache a call that returns a deallocated pointer. */
- if (cacheable && (cp_walk_tree_without_duplicates
- (&result, find_heap_var_refs, NULL)))
- cacheable = false;
}
/* Rewrite all occurrences of the function's RESULT_DECL with the
@@ -3217,6 +3213,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
&& !is_empty_class (TREE_TYPE (res)))
if (replace_decl (&result, res, ctx->object))
cacheable = false;
+
+ /* Only cache a permitted result of a constant expression. */
+ if (cacheable && !reduced_constant_expression_p (result))
+ cacheable = false;
}
else
/* Couldn't get a function copy to evaluate. */
@@ -3268,8 +3268,9 @@ reduced_constant_expression_p (tree t)
case CONSTRUCTOR:
/* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
tree field;
- if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
- /* An initialized vector would have a VECTOR_CST. */
+ if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
+ /* A constant vector would be folded to VECTOR_CST.
+ A CONSTRUCTOR of scalar type means uninitialized. */
return false;
if (CONSTRUCTOR_NO_CLEARING (t))
{