Skip to content

Commit 55250bf

Browse files
committed
gccrs: feat: Made changes to ensure no wrong assignments are done.
gcc/rust/ChangeLog: * backend/rust-compile-base.cc (HIRCompileBase::is_lvalue): Created a function that checks for lvalue. * backend/rust-compile-base.h: Created the Signature for above function. * backend/rust-compile-expr.cc (CompileExpr::visit): Made changes to ensure proper readability and checking for wrong assignments in AssignmentExpr and CompoundAssignmentExpr Respectively. gcc/testsuite/ChangeLog: * rust/compile/issue-3297.rs: New test (New Feature). * rust/compile/issue-3297-2.rs: New test (Regression). * rust/compile/issue-3297-3.rs: New test (New Feature). Signed-off-by: Sri Ganesh Thota <[email protected]>
1 parent 55a9d8d commit 55250bf

File tree

6 files changed

+82
-0
lines changed

6 files changed

+82
-0
lines changed

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,5 +1015,52 @@ HIRCompileBase::unit_expression (location_t locus)
10151015
return Backend::constructor_expression (unit_type, false, {}, -1, locus);
10161016
}
10171017

1018+
bool
1019+
HIRCompileBase::is_lvalue (const_tree ref)
1020+
{
1021+
const enum tree_code code = TREE_CODE (ref);
1022+
1023+
switch (code)
1024+
{
1025+
case REALPART_EXPR:
1026+
case IMAGPART_EXPR:
1027+
case COMPONENT_REF:
1028+
return is_lvalue (TREE_OPERAND (ref, 0));
1029+
1030+
case COMPOUND_LITERAL_EXPR:
1031+
case STRING_CST:
1032+
case CONST_DECL:
1033+
case INTEGER_CST:
1034+
return true;
1035+
1036+
case MEM_REF:
1037+
case TARGET_MEM_REF:
1038+
/* MEM_REFs can appear from -fgimple parsing or folding, so allow them
1039+
here as well. */
1040+
case INDIRECT_REF:
1041+
return true;
1042+
case ARRAY_REF:
1043+
case VAR_DECL:
1044+
case PARM_DECL:
1045+
case RESULT_DECL:
1046+
case ERROR_MARK:
1047+
return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
1048+
&& TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
1049+
1050+
case BIND_EXPR:
1051+
return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
1052+
case PLUS_EXPR:
1053+
case MINUS_EXPR:
1054+
case MULT_EXPR:
1055+
case POINTER_PLUS_EXPR:
1056+
case POINTER_DIFF_EXPR:
1057+
case MULT_HIGHPART_EXPR:
1058+
case TRUNC_DIV_EXPR:
1059+
return false;
1060+
default:
1061+
return false;
1062+
}
1063+
}
1064+
10181065
} // namespace Compile
10191066
} // namespace Rust

gcc/rust/backend/rust-compile-base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class HIRCompileBase
3030
virtual ~HIRCompileBase () {}
3131

3232
static tree address_expression (tree expr, location_t locus);
33+
bool is_lvalue (const_tree ref);
3334

3435
protected:
3536
HIRCompileBase (Context *ctx) : ctx (ctx) {}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
188188
auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
189189
auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
190190

191+
bool validl_value = is_lvalue (lhs);
192+
193+
if (!validl_value
194+
|| (expr.get_lhs ().get_expression_type ()
195+
== HIR::Expr::ExprType::Operator
196+
&& TREE_CODE (lhs) != INDIRECT_REF))
197+
{
198+
rust_error_at (expr.get_lhs ().get_locus (), ErrorCode::E0770,
199+
"invalid left-hand side of assignment");
200+
return;
201+
}
191202
// this might be an operator overload situation lets check
192203
TyTy::FnType *fntype;
193204
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
@@ -964,6 +975,17 @@ CompileExpr::visit (HIR::AssignmentExpr &expr)
964975
auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
965976
auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
966977

978+
bool validl_value = is_lvalue (lvalue);
979+
980+
if (!validl_value
981+
|| expr.get_lhs ().get_expression_type ()
982+
== HIR::Expr::ExprType::Operator)
983+
{
984+
rust_error_at (expr.get_lhs ().get_locus (), ErrorCode::E0770,
985+
"invalid left-hand side of assignment");
986+
return;
987+
}
988+
967989
// assignments are coercion sites so lets convert the rvalue if necessary
968990
TyTy::BaseType *expected = nullptr;
969991
TyTy::BaseType *actual = nullptr;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub fn main() {
2+
let mut x = 42;
3+
x += 1;
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub fn main() {
2+
let mut x = 42;
3+
x + 1 += 1; // { dg-error "invalid left-hand side of assignment" }
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub fn main() {
2+
let mut x = 42;
3+
x + 1= 2; // { dg-error "invalid left-hand side of assignment" }
4+
}

0 commit comments

Comments
 (0)