diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-11-15 12:10:16 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-11-15 12:10:16 -0500 |
commit | d3f48f682271ed94ab6e9f6bc62418a62bd8ff26 (patch) | |
tree | 6c4c856828b6524e3ea4d7c73403c5b69f1001de /gcc/cp/tree.cc | |
parent | 6665a8572c8f24bd55c6081c91f461442c94dcfb (diff) | |
download | gcc-d3f48f682271ed94ab6e9f6bc62418a62bd8ff26.zip gcc-d3f48f682271ed94ab6e9f6bc62418a62bd8ff26.tar.gz gcc-d3f48f682271ed94ab6e9f6bc62418a62bd8ff26.tar.bz2 |
c++: non-dependent .* operand folding [PR112427]
Here when building up the non-dependent .* expression, we crash from
fold_convert on 'b.a' due to this (templated) COMPONENT_REF having an
IDENTIFIER_NODE instead of FIELD_DECL operand that middle-end routines
expect. Like in r14-4899-gd80a26cca02587, this patch fixes this by
replacing the problematic piecemeal folding with a single call to
cp_fully_fold. Also, don't bother building the POINTER_PLUS_EXPR in a
template context. This means the returned non-dependent tree might not
have TREE_SIDE_EFFECTS set when it used to, so we need to compensate
by making build_min_non_dep propagate TREE_SIDE_EFFECTS from the original
arguments like buildN and build_min do.
PR c++/112427
gcc/cp/ChangeLog:
* tree.cc (build_min_non_dep): Propagate TREE_SIDE_EFFECTS from
the original arguments.
(build_min_non_dep_call_vec): Likewise.
* typeck2.cc (build_m_component_ref): Use cp_convert, build2 and
cp_fully_fold instead of fold_build_pointer_plus and fold_convert.
Don't build the POINTER_PLUS_EXPR in a template context.
gcc/testsuite/ChangeLog:
* g++.dg/template/non-dependent29.C: New test.
Diffstat (limited to 'gcc/cp/tree.cc')
-rw-r--r-- | gcc/cp/tree.cc | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 417c92b..dc4126f 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -3601,7 +3601,12 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...) TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep); for (i = 0; i < length; i++) - TREE_OPERAND (t, i) = va_arg (p, tree); + { + tree x = va_arg (p, tree); + TREE_OPERAND (t, i) = x; + if (x && !TYPE_P (x)) + TREE_SIDE_EFFECTS (t) |= TREE_SIDE_EFFECTS (x); + } va_end (p); return convert_from_reference (t); @@ -3636,6 +3641,10 @@ build_min_non_dep_call_vec (tree non_dep, tree fn, vec<tree, va_gc> *argvec) non_dep = TREE_OPERAND (non_dep, 0); TREE_TYPE (t) = TREE_TYPE (non_dep); TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep); + if (argvec) + for (tree x : *argvec) + if (x && !TYPE_P (x)) + TREE_SIDE_EFFECTS (t) |= TREE_SIDE_EFFECTS (x); return convert_from_reference (t); } |