Skip to content

Commit e8f8dbc

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 c185688 commit e8f8dbc

File tree

6 files changed

+83
-0
lines changed

6 files changed

+83
-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+
rust_debug ("Hocus: %d", code);
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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
190190
auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
191191
auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
192192

193+
bool validl_value = is_lvalue (lhs);
194+
195+
if (!validl_value
196+
|| (expr.get_lhs ().get_expression_type ()
197+
== HIR::Expr::ExprType::Operator
198+
&& TREE_CODE (lhs) != INDIRECT_REF
199+
&& TREE_CODE (lhs) != COMPONENT_REF))
200+
{
201+
rust_error_at (expr.get_lhs ().get_locus (), ErrorCode::E0770,
202+
"invalid left-hand side of assignment");
203+
return;
204+
}
193205
// this might be an operator overload situation lets check
194206
TyTy::FnType *fntype;
195207
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
@@ -994,6 +1006,17 @@ CompileExpr::visit (HIR::AssignmentExpr &expr)
9941006
auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
9951007
auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
9961008

1009+
bool validl_value = is_lvalue (lvalue);
1010+
1011+
if (!validl_value
1012+
|| expr.get_lhs ().get_expression_type ()
1013+
== HIR::Expr::ExprType::Operator)
1014+
{
1015+
rust_error_at (expr.get_lhs ().get_locus (), ErrorCode::E0770,
1016+
"invalid left-hand side of assignment");
1017+
return;
1018+
}
1019+
9971020
// assignments are coercion sites so lets convert the rvalue if necessary
9981021
TyTy::BaseType *expected = nullptr;
9991022
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)