public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-160] c++: empty base constexpr adjustment [PR105245]
@ 2022-05-06 20:30 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-05-06 20:30 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:967cdbe66296535fa496b88406a1125c8acaf6e2
commit r13-160-g967cdbe66296535fa496b88406a1125c8acaf6e2
Author: Jason Merrill <jason@redhat.com>
Date: Tue Apr 12 17:46:59 2022 -0400
c++: empty base constexpr adjustment [PR105245]
While looking at PR105245 in stage 4, I wanted to reorganize the code a bit,
but it seemed prudent to defer that to stage 1.
PR c++/105245
PR c++/100111
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_store_expression): Reorganize empty base
handling.
Diff:
---
gcc/cp/constexpr.cc | 69 +++++++++++++++++++++++++++--------------------------
1 file changed, 35 insertions(+), 34 deletions(-)
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 9b1e71857fc..6c204ab2265 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -5718,6 +5718,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
releasing_vec ctors, indexes;
auto_vec<int> index_pos_hints;
bool activated_union_member_p = false;
+ bool empty_base = false;
while (!refs->is_empty ())
{
if (*valp == NULL_TREE)
@@ -5759,7 +5760,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
enum tree_code code = TREE_CODE (type);
- type = refs->pop();
+ tree reftype = refs->pop();
tree index = refs->pop();
if (code == RECORD_TYPE && is_empty_field (index))
@@ -5768,7 +5769,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
fields, which confuses the middle-end. The code below will notice
that we don't have a CONSTRUCTOR for our inner target and just
return init. */
- break;
+ {
+ empty_base = true;
+ break;
+ }
+
+ type = reftype;
if (code == UNION_TYPE && CONSTRUCTOR_NELTS (*valp)
&& CONSTRUCTOR_ELT (*valp, 0)->index != index)
@@ -5902,44 +5908,41 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
}
}
+ if (*non_constant_p)
+ return t;
+
/* Don't share a CONSTRUCTOR that might be changed later. */
init = unshare_constructor (init);
- if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
- && TREE_CODE (init) == CONSTRUCTOR)
+ gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (*valp), type)));
+ if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (init), type)))
{
- /* An outer ctx->ctor might be pointing to *valp, so replace
- its contents. */
- if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- TREE_TYPE (*valp)))
- {
- /* For initialization of an empty base, the original target will be
- *(base*)this, evaluation of which resolves to the object
- argument, which has the derived type rather than the base type. In
- this situation, just evaluate the initializer and return, since
- there's no actual data to store. */
- gcc_assert (is_empty_class (TREE_TYPE (init)));
- return lval ? target : init;
- }
- CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
- TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
- TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
- CONSTRUCTOR_NO_CLEARING (*valp)
- = CONSTRUCTOR_NO_CLEARING (init);
- }
- else if (TREE_CODE (init) == CONSTRUCTOR
- && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- type))
- {
- /* See above on initialization of empty bases. */
- gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
+ /* For initialization of an empty base, the original target will be
+ *(base*)this, evaluation of which resolves to the object
+ argument, which has the derived type rather than the base type. In
+ this situation, just evaluate the initializer and return, since
+ there's no actual data to store, and we didn't build a CONSTRUCTOR. */
+ empty_base = true;
+ gcc_assert (is_empty_class (TREE_TYPE (init)));
if (!*valp)
{
/* But do make sure we have something in *valp. */
*valp = build_constructor (type, nullptr);
CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
}
- return init;
+ }
+ else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
+ && TREE_CODE (init) == CONSTRUCTOR)
+ {
+ /* An outer ctx->ctor might be pointing to *valp, so replace
+ its contents. */
+ CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
+ TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
+ TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
+ CONSTRUCTOR_NO_CLEARING (*valp)
+ = CONSTRUCTOR_NO_CLEARING (init);
}
else
*valp = init;
@@ -5958,7 +5961,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
constructor of a delegating constructor). Leave it up to the
caller that set 'this' to set TREE_READONLY appropriately. */
gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (target), type));
+ (TREE_TYPE (target), type) || empty_base);
else
TREE_READONLY (*valp) = true;
}
@@ -5980,9 +5983,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
CONSTRUCTOR_NO_CLEARING (elt) = false;
}
- if (*non_constant_p)
- return t;
- else if (lval)
+ if (lval)
return target;
else
return init;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-05-06 20:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06 20:30 [gcc r13-160] c++: empty base constexpr adjustment [PR105245] Jason Merrill
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).