Tested x86_64-pc-linux-gnu, applying to trunk. -- >8 --
I was wondering how lvalue_kind handles VIEW_CONVERT_EXPR; in cases where the type actually changes, it should have the same prvalue->xvalue effect as ARRAY_REF, since we need to materialize a temporary to get an object we can reinterpret as another type. Currently this only fires on builtin-shufflevector-3.c, where we use VIEW_CONVERT_EXPR to reinterpret a vector as an array. REALPART_EXPR and IMAGPART_EXPR should also be treated like COMPONENT_REF. PREINCREMENT_EXPR and PREDECREMENT_EXPR should only be applied to glvalues, but if for some reason they were applied to a prvalue this would be correct. TRY_CATCH_EXPR around a prvalue is also questionable, but this is the right handling. gcc/cp/ChangeLog: * tree.cc (lvalue_kind) [VIEW_CONVERT_EXPR]: Change prvalue to xvalue. --- gcc/cp/tree.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index aa9c1b7d8f9..6d968a2af11 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -104,7 +104,17 @@ lvalue_kind (const_tree ref) case REALPART_EXPR: case IMAGPART_EXPR: case VIEW_CONVERT_EXPR: - return lvalue_kind (TREE_OPERAND (ref, 0)); + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); + /* As for ARRAY_REF and COMPONENT_REF, these codes turn a class prvalue + into an xvalue: we need to materialize the temporary before we mess + with it. Except VIEW_CONVERT_EXPR that doesn't actually change the + type, as in location wrapper and REF_PARENTHESIZED_P. */ + if (op1_lvalue_kind == clk_class + && !(TREE_CODE (ref) == VIEW_CONVERT_EXPR + && (same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (ref), TREE_TYPE (TREE_OPERAND (ref, 0)))))) + return clk_rvalueref; + return op1_lvalue_kind; case ARRAY_REF: { base-commit: 7d935cdd1a6772699ec0ab4f93711928ca4d30a1 -- 2.31.1