Skip to content

Commit 167b909

Browse files
committed
gccrs: feat: Made changes to ensure no wrong assignments are done.
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.
1 parent 55a9d8d commit 167b909

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

gcc/rust/backend/rust-compile-expr.cc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,12 +958,71 @@ CompileExpr::visit (HIR::LiteralExpr &expr)
958958
}
959959
}
960960

961+
bool
962+
lvalue_p (const_tree ref)
963+
{
964+
const enum tree_code code = TREE_CODE (ref);
965+
966+
switch (code)
967+
{
968+
case REALPART_EXPR:
969+
case IMAGPART_EXPR:
970+
case COMPONENT_REF:
971+
return lvalue_p (TREE_OPERAND (ref, 0));
972+
973+
case C_MAYBE_CONST_EXPR:
974+
return lvalue_p (TREE_OPERAND (ref, 1));
975+
976+
case COMPOUND_LITERAL_EXPR:
977+
case STRING_CST:
978+
case CONST_DECL:
979+
case INTEGER_CST:
980+
return true;
981+
982+
case MEM_REF:
983+
case TARGET_MEM_REF:
984+
/* MEM_REFs can appear from -fgimple parsing or folding, so allow them
985+
here as well. */
986+
case INDIRECT_REF:
987+
case ARRAY_REF:
988+
case VAR_DECL:
989+
case PARM_DECL:
990+
case RESULT_DECL:
991+
case ERROR_MARK:
992+
return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
993+
&& TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
994+
995+
case BIND_EXPR:
996+
return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
997+
case PLUS_EXPR:
998+
case MINUS_EXPR:
999+
case MULT_EXPR:
1000+
case POINTER_PLUS_EXPR:
1001+
case POINTER_DIFF_EXPR:
1002+
case MULT_HIGHPART_EXPR:
1003+
case TRUNC_DIV_EXPR:
1004+
return false;
1005+
default:
1006+
rust_debug ("unknown");
1007+
return false;
1008+
}
1009+
}
1010+
9611011
void
9621012
CompileExpr::visit (HIR::AssignmentExpr &expr)
9631013
{
9641014
auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
9651015
auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
9661016

1017+
if (!lvalue_p (lvalue)
1018+
|| expr.get_lhs ().get_expression_type ()
1019+
== HIR::Expr::ExprType::Operator)
1020+
{
1021+
rust_error_at (expr.get_lhs ().get_locus (),
1022+
"invalid left-hand side of assignment");
1023+
return;
1024+
}
1025+
9671026
// assignments are coercion sites so lets convert the rvalue if necessary
9681027
TyTy::BaseType *expected = nullptr;
9691028
TyTy::BaseType *actual = nullptr;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extern "C" {
2+
fn printf(s: *const i8, ...);
3+
}
4+
5+
pub fn main() {
6+
unsafe {
7+
let mut x = 42;
8+
x + 1= 2; // { dg-error "invalid left-hand side of assignment" }
9+
let format = "Result: %d\n\0" as *const str as *const i8;
10+
printf(format, x);
11+
}
12+
}

0 commit comments

Comments
 (0)