Skip to content

Commit

Permalink
gccrs: feat: Made changes to ensure no wrong assignments are done.
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc (lvalue_p): Created a function that checks the lvalue.
	(CompileExpr::visit): Modified the function to check the lvalue using the above mentioned
        function and also checks the type of lvalue expression.

gcc/testsuite/ChangeLog:

	* rust/compile/issue-3287.rs: New test for testing wrong assignments.
  • Loading branch information
sriganeshres committed Dec 11, 2024
1 parent 55a9d8d commit 41640eb
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
59 changes: 59 additions & 0 deletions gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -958,12 +958,71 @@ 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)
|| 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;
Expand Down
12 changes: 12 additions & 0 deletions gcc/testsuite/rust/compile/issue-3287.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 41640eb

Please sign in to comment.