diff options
author | Jason Merrill <jason@redhat.com> | 2021-01-25 17:02:57 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-04-29 14:41:45 -0400 |
commit | bc99c54de5a262ffc5f7801e16d919d335a53a8b (patch) | |
tree | 2feef056d55d6a95faa2e9ee5437e03e64448f3c | |
parent | a0fdff3cf33f72848d3f894272431a5d49fe6a16 (diff) | |
download | gcc-bc99c54de5a262ffc5f7801e16d919d335a53a8b.zip gcc-bc99c54de5a262ffc5f7801e16d919d335a53a8b.tar.gz gcc-bc99c54de5a262ffc5f7801e16d919d335a53a8b.tar.bz2 |
c++: Use empty field in constexpr eval.
In discussion of PR98463, Jakub noted that cxx_fold_indirect_ref_1 was
bailing out early for empty bases even when we do have fields for them (in
C++17 mode or later). This corrects that.
gcc/cp/ChangeLog:
* constexpr.c (cxx_fold_indirect_ref_1): Only set *empty_base if we
don't find a field.
-rw-r--r-- | gcc/cp/constexpr.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index fa7eaed..9481a5b 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4734,28 +4734,17 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, { tree optype = TREE_TYPE (op); unsigned HOST_WIDE_INT const_nunits; - if (off == 0) + if (off == 0 && similar_type_p (optype, type)) + return op; + else if (TREE_CODE (optype) == COMPLEX_TYPE + && similar_type_p (type, TREE_TYPE (optype))) { - if (similar_type_p (optype, type)) - return op; - /* Also handle conversion to an empty base class, which - is represented with a NOP_EXPR. */ /* *(foo *)&complexfoo => __real__ complexfoo */ - else if (TREE_CODE (optype) == COMPLEX_TYPE - && similar_type_p (type, TREE_TYPE (optype))) + if (off == 0) return build1_loc (loc, REALPART_EXPR, type, op); - } - /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ - else if (TREE_CODE (optype) == COMPLEX_TYPE - && similar_type_p (type, TREE_TYPE (optype)) - && tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off) - return build1_loc (loc, IMAGPART_EXPR, type, op); - if (is_empty_class (type) - && CLASS_TYPE_P (optype) - && DERIVED_FROM_P (type, optype)) - { - *empty_base = true; - return op; + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ + else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off) + return build1_loc (loc, IMAGPART_EXPR, type, op); } /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */ else if (VECTOR_TYPE_P (optype) @@ -4834,6 +4823,15 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, return ret; } } + /* Also handle conversion to an empty base class, which + is represented with a NOP_EXPR. */ + if (is_empty_class (type) + && CLASS_TYPE_P (optype) + && DERIVED_FROM_P (type, optype)) + { + *empty_base = true; + return op; + } } return NULL_TREE; |