From ba91a60669ae5788d2dfd795c09a8657f4963265 Mon Sep 17 00:00:00 2001 From: Sri Ganesh Thota Date: Wed, 11 Dec 2024 22:44:52 +0530 Subject: [PATCH] gccrs: feat: Made changes to ensure no wrong assignments are done. gcc/rust/ChangeLog: * backend/rust-compile-base.cc (HIRCompileBase::lvalue_p): Created a function that checks the lvalue. * backend/rust-compile-base.h: Created the Signature for above function * backend/rust-compile-expr.cc (lvalue_p): Moved the function from here to rust-compile-base. (CompileExpr::visit): Made changes to ensure proper readability and checking for wrong assignments. Signed-off-by: Sri Ganesh Thota --- gcc/rust/backend/rust-compile-base.cc | 46 ++++++++++++++++++++++++ gcc/rust/backend/rust-compile-base.h | 1 + gcc/rust/backend/rust-compile-expr.cc | 13 ++++++- gcc/testsuite/rust/compile/issue-3287.rs | 12 +++++++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/rust/compile/issue-3287.rs diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index a4d0d062accc..b17c354b41e4 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 3c50535552f5..5d9b015d94eb 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 7323413bfce2..af8b73e88430 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -851,7 +851,7 @@ CompileExpr::visit (HIR::ContinueExpr &expr) if (!ctx->lookup_label_decl (ref, &label)) { - rust_error_at (expr.get_label ().get_locus (), + rust_error_at (expr.get_label ().get_locus (), ErrorCode::E0770, "failed to lookup compiled label"); return; } @@ -964,6 +964,17 @@ CompileExpr::visit (HIR::AssignmentExpr &expr) auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx); auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx); + 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"); + return; + } + // assignments are coercion sites so lets convert the rvalue if necessary TyTy::BaseType *expected = nullptr; TyTy::BaseType *actual = nullptr; diff --git a/gcc/testsuite/rust/compile/issue-3287.rs b/gcc/testsuite/rust/compile/issue-3287.rs new file mode 100644 index 000000000000..c1ea9f63af64 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3287.rs @@ -0,0 +1,12 @@ +extern "C" { + fn printf(s: *const i8, ...); +} + +pub fn main() { + unsafe { + let mut x = 42; + x + 1= 2; // { dg-error "invalid left-hand side of assignment" } + let format = "Result: %d\n\0" as *const str as *const i8; + printf(format, x); + } +} \ No newline at end of file