diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index a4d0d062acc..b17c354b41e 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -1015,5 +1015,51 @@ HIRCompileBase::unit_expression (location_t locus) return Backend::constructor_expression (unit_type, false, {}, -1, locus); } +bool +HIRCompileBase::lvalue_p (const_tree ref) +{ + const enum tree_code code = TREE_CODE (ref); + + switch (code) + { + case REALPART_EXPR: + case IMAGPART_EXPR: + case COMPONENT_REF: + return lvalue_p (TREE_OPERAND (ref, 0)); + + case COMPOUND_LITERAL_EXPR: + case STRING_CST: + case CONST_DECL: + case INTEGER_CST: + return true; + + case MEM_REF: + case TARGET_MEM_REF: + /* MEM_REFs can appear from -fgimple parsing or folding, so allow them + here as well. */ + case INDIRECT_REF: + case ARRAY_REF: + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + case ERROR_MARK: + return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); + + case BIND_EXPR: + return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case POINTER_PLUS_EXPR: + case POINTER_DIFF_EXPR: + case MULT_HIGHPART_EXPR: + case TRUNC_DIV_EXPR: + return false; + default: + return false; + } +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 3c50535552f..5d9b015d94e 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -30,6 +30,7 @@ class HIRCompileBase virtual ~HIRCompileBase () {} static tree address_expression (tree expr, location_t locus); + bool lvalue_p (const_tree ref); protected: HIRCompileBase (Context *ctx) : ctx (ctx) {} diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 1a3ba1961e0..ab0e8a45818 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -958,68 +958,20 @@ CompileExpr::visit (HIR::LiteralExpr &expr) } } -bool -lvalue_p (const_tree ref) -{ - const enum tree_code code = TREE_CODE (ref); - - switch (code) - { - case REALPART_EXPR: - case IMAGPART_EXPR: - case COMPONENT_REF: - return lvalue_p (TREE_OPERAND (ref, 0)); - - case C_MAYBE_CONST_EXPR: - return lvalue_p (TREE_OPERAND (ref, 1)); - - case COMPOUND_LITERAL_EXPR: - case STRING_CST: - case CONST_DECL: - case INTEGER_CST: - return true; - - case MEM_REF: - case TARGET_MEM_REF: - /* MEM_REFs can appear from -fgimple parsing or folding, so allow them - here as well. */ - case INDIRECT_REF: - case ARRAY_REF: - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - case ERROR_MARK: - return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); - - case BIND_EXPR: - return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case POINTER_PLUS_EXPR: - case POINTER_DIFF_EXPR: - case MULT_HIGHPART_EXPR: - case TRUNC_DIV_EXPR: - return false; - default: - rust_debug ("unknown"); - return false; - } -} - void CompileExpr::visit (HIR::AssignmentExpr &expr) { auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx); auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx); - if (!lvalue_p (lvalue) + bool validl_value = lvalue_p (lvalue); + + if (!validl_value || expr.get_lhs ().get_expression_type () == HIR::Expr::ExprType::Operator) { - rust_error_at (expr.get_lhs ().get_locus (), - "invalid left-hand side of assignment"); + rust_fatal_error (expr.get_lhs ().get_locus (), + "invalid left-hand side of assignment"); return; }