From 7a5dd3ed49d1b328865520ee30e758158516ca2b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 4 May 2021 21:33:33 -0400 Subject: [PATCH] c++: reject class lvalues in 'rvalue' Wrapping a class lvalue in NON_LVALUE_EXPR is not sufficient to make it a usable prvalue; callers must use force_rvalue instead. 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 4ccd7a3..7f148b4 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); -- 2.7.4