From: Jason Merrill Date: Mon, 25 Jan 2021 22:02:57 +0000 (-0500) Subject: c++: Use empty field in constexpr eval. X-Git-Tag: basepoints/gcc-13~8013 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bc99c54de5a262ffc5f7801e16d919d335a53a8b;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index fa7eaed945a4..9481a5bfd3c2 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 */ 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;