Message ID | 20240515175548.591253-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: represent all class non-dep assignments as CALL_EXPR | expand |
On 5/15/24 13:55, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linu-xgnu, does this look OK > for trunk? OK. > -- >8 -- > > Non-dependent compound assignment expressions are currently represented > as CALL_EXPR to the selected operator@= overload. Non-dependent simple > assignments on the other hand are still represented as MODOP_EXPR, which > doesn't hold on to the selected overload. > > That we need to remember the selected operator@= overload ahead of time > is a correctness thing, because they can be declared at namespace scope > and we don't want to consider later-declared namespace scope overloads > at instantiation time. This doesn't apply to simple operator= because > it can only be declared at class scope, so it's fine to repeat the name > lookup and overload resolution at instantiation time. But it still > seems desirable for sake of QoI to also avoid this repeated name lookup > and overload resolution for simple assignments along the lines of > r12-6075-g2decd2cabe5a4f. > > To that end, this patch makes us represent non-dependent simple > assignments as CALL_EXPR to the selected operator= overload rather than > as MODOP_EXPR. In order for is_assignment_op_expr_p to recognize such > CALL_EXPR as an assignment expression, cp_get_fndecl_from_callee needs > to look through templated COMPONENT_REF callee corresponding to a member > function call, otherwise ahead of time -Wparentheses warnings stop > working (e.g. g++.dg/warn/Wparentheses-{32,33}.C). > > gcc/cp/ChangeLog: > > * call.cc (build_new_op): Pass 'overload' to > cp_build_modify_expr. > * cp-tree.h (cp_build_modify_expr): New overload that > takes a tree* out-parameter. > * pt.cc (tsubst_expr) <case CALL_EXPR>: Propagate > OPT_Wparentheses warning suppression to the result. > * cvt.cc (cp_get_fndecl_from_callee): Use maybe_get_fns > to extract the FUNCTION_DECL from a callee. > * semantics.cc (is_assignment_op_expr_p): Also recognize > templated operator expressions represented as a CALL_EXPR > to operator=. > * typeck.cc (cp_build_modify_expr): Add 'overload' > out-parameter and pass it to build_new_op. > (build_x_modify_expr): Pass 'overload' to cp_build_modify_expr. > --- > gcc/cp/call.cc | 2 +- > gcc/cp/cp-tree.h | 3 +++ > gcc/cp/cvt.cc | 5 +++-- > gcc/cp/pt.cc | 2 ++ > gcc/cp/typeck.cc | 18 ++++++++++++++---- > 5 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index e058da7735f..e3d4cf8949d 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -7473,7 +7473,7 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags, > switch (code) > { > case MODIFY_EXPR: > - return cp_build_modify_expr (loc, arg1, code2, arg2, complain); > + return cp_build_modify_expr (loc, arg1, code2, arg2, overload, complain); > > case INDIRECT_REF: > return cp_build_indirect_ref (loc, arg1, RO_UNARY_STAR, complain); > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 9a8c8659157..1e565086e80 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -8267,6 +8267,9 @@ extern tree cp_build_c_cast (location_t, tree, tree, > extern cp_expr build_x_modify_expr (location_t, tree, > enum tree_code, tree, > tree, tsubst_flags_t); > +extern tree cp_build_modify_expr (location_t, tree, > + enum tree_code, tree, > + tree *, tsubst_flags_t); > extern tree cp_build_modify_expr (location_t, tree, > enum tree_code, tree, > tsubst_flags_t); > diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc > index db086c017e8..2f4c0f88694 100644 > --- a/gcc/cp/cvt.cc > +++ b/gcc/cp/cvt.cc > @@ -1015,8 +1015,9 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */) > return f; > }; > > - if (TREE_CODE (fn) == FUNCTION_DECL) > - return fn_or_local_alias (fn); > + if (tree f = maybe_get_fns (fn)) > + if (TREE_CODE (f) == FUNCTION_DECL) > + return fn_or_local_alias (f); > tree type = TREE_TYPE (fn); > if (type == NULL_TREE || !INDIRECT_TYPE_P (type)) > return NULL_TREE; > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 32640f8e946..d83f530ac8d 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -21093,6 +21093,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) > if (warning_suppressed_p (t, OPT_Wpessimizing_move)) > /* This also suppresses -Wredundant-move. */ > suppress_warning (ret, OPT_Wpessimizing_move); > + if (warning_suppressed_p (t, OPT_Wparentheses)) > + suppress_warning (STRIP_REFERENCE_REF (ret), OPT_Wparentheses); > } > > RETURN (ret); > diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc > index 5f16994300f..75b696e32e0 100644 > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -9421,7 +9421,7 @@ build_modify_expr (location_t location, > > tree > cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > - tree rhs, tsubst_flags_t complain) > + tree rhs, tree *overload, tsubst_flags_t complain) > { > lhs = mark_lvalue_use_nonread (lhs); > > @@ -9533,7 +9533,8 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > rhs = unshare_expr (rhs); > tree op2 = TREE_OPERAND (lhs, 2); > if (TREE_CODE (op2) != THROW_EXPR) > - op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain); > + op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, > + overload, complain); > tree cond = build_conditional_expr (input_location, > TREE_OPERAND (lhs, 0), op1, op2, > complain); > @@ -9620,7 +9621,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > result = build_new_op (input_location, MODIFY_EXPR, > LOOKUP_NORMAL, lhs, rhs, > make_node (NOP_EXPR), NULL_TREE, > - /*overload=*/NULL, complain); > + overload, complain); > if (result == NULL_TREE) > return error_mark_node; > goto ret; > @@ -9828,6 +9829,14 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > return result; > } > > +tree > +cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > + tree rhs, tsubst_flags_t complain) > +{ > + return cp_build_modify_expr (loc, lhs, modifycode, rhs, > + /*overload=*/nullptr, complain); > +} > + > cp_expr > build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > tree rhs, tree lookups, tsubst_flags_t complain) > @@ -9856,7 +9865,8 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > > tree rval; > if (modifycode == NOP_EXPR) > - rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain); > + rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, > + &overload, complain); > else > rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, > lhs, rhs, op, lookups, &overload, complain);
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index e058da7735f..e3d4cf8949d 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -7473,7 +7473,7 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags, switch (code) { case MODIFY_EXPR: - return cp_build_modify_expr (loc, arg1, code2, arg2, complain); + return cp_build_modify_expr (loc, arg1, code2, arg2, overload, complain); case INDIRECT_REF: return cp_build_indirect_ref (loc, arg1, RO_UNARY_STAR, complain); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9a8c8659157..1e565086e80 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8267,6 +8267,9 @@ extern tree cp_build_c_cast (location_t, tree, tree, extern cp_expr build_x_modify_expr (location_t, tree, enum tree_code, tree, tree, tsubst_flags_t); +extern tree cp_build_modify_expr (location_t, tree, + enum tree_code, tree, + tree *, tsubst_flags_t); extern tree cp_build_modify_expr (location_t, tree, enum tree_code, tree, tsubst_flags_t); diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index db086c017e8..2f4c0f88694 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1015,8 +1015,9 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */) return f; }; - if (TREE_CODE (fn) == FUNCTION_DECL) - return fn_or_local_alias (fn); + if (tree f = maybe_get_fns (fn)) + if (TREE_CODE (f) == FUNCTION_DECL) + return fn_or_local_alias (f); tree type = TREE_TYPE (fn); if (type == NULL_TREE || !INDIRECT_TYPE_P (type)) return NULL_TREE; diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 32640f8e946..d83f530ac8d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21093,6 +21093,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (warning_suppressed_p (t, OPT_Wpessimizing_move)) /* This also suppresses -Wredundant-move. */ suppress_warning (ret, OPT_Wpessimizing_move); + if (warning_suppressed_p (t, OPT_Wparentheses)) + suppress_warning (STRIP_REFERENCE_REF (ret), OPT_Wparentheses); } RETURN (ret); diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 5f16994300f..75b696e32e0 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -9421,7 +9421,7 @@ build_modify_expr (location_t location, tree cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, - tree rhs, tsubst_flags_t complain) + tree rhs, tree *overload, tsubst_flags_t complain) { lhs = mark_lvalue_use_nonread (lhs); @@ -9533,7 +9533,8 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, rhs = unshare_expr (rhs); tree op2 = TREE_OPERAND (lhs, 2); if (TREE_CODE (op2) != THROW_EXPR) - op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain); + op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, + overload, complain); tree cond = build_conditional_expr (input_location, TREE_OPERAND (lhs, 0), op1, op2, complain); @@ -9620,7 +9621,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, result = build_new_op (input_location, MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, make_node (NOP_EXPR), NULL_TREE, - /*overload=*/NULL, complain); + overload, complain); if (result == NULL_TREE) return error_mark_node; goto ret; @@ -9828,6 +9829,14 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, return result; } +tree +cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, + tree rhs, tsubst_flags_t complain) +{ + return cp_build_modify_expr (loc, lhs, modifycode, rhs, + /*overload=*/nullptr, complain); +} + cp_expr build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, tree rhs, tree lookups, tsubst_flags_t complain) @@ -9856,7 +9865,8 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, tree rval; if (modifycode == NOP_EXPR) - rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain); + rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, + &overload, complain); else rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, op, lookups, &overload, complain);