Wrapping a class lvalue in NON_LVALUE_EXPR is not sufficient to make it a usable prvalue; callers must use force_rvalue instead.
Tested x86_64-pc-linux-gnu, applying to trunk. gcc/cp/ChangeLog: * tree.c (rvalue): Assert expr is not a class lvalue. --- gcc/cp/tree.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4ccd7a314f5..7f148b4b158 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -940,7 +940,12 @@ rvalue (tree expr) /* We need to do this for rvalue refs as well to get the right answer from decltype; see c++/36628. */ if (!processing_template_decl && glvalue_p (expr)) - expr = build1 (NON_LVALUE_EXPR, type, expr); + { + /* But don't use this function for class lvalues; use move (to treat an + lvalue as an xvalue) or force_rvalue (to make a prvalue copy). */ + gcc_checking_assert (!CLASS_TYPE_P (type)); + expr = build1 (NON_LVALUE_EXPR, type, expr); + } else if (type != TREE_TYPE (expr)) expr = build_nop (type, expr); base-commit: fc178519771db508c03611cff4a1466cf67fce1d -- 2.27.0