aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-19 17:29:10 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-20 10:02:41 +0000
commit6e09093f1f759a78387d214b6d0fe8ba17b752b6 (patch)
tree816f115416b052e671e77b8367d49e0ec767d9e1 /gcc
parent76b308af7e69f5b50fee96ba4b3584935e621259 (diff)
downloadgcc-6e09093f1f759a78387d214b6d0fe8ba17b752b6.zip
gcc-6e09093f1f759a78387d214b6d0fe8ba17b752b6.tar.gz
gcc-6e09093f1f759a78387d214b6d0fe8ba17b752b6.tar.bz2
Enforce the rules for arithmetic operations
This adds test cases and enforces the type rules for ArithmeticOrLogical Operators.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h55
-rw-r--r--gcc/testsuite/rust.test/compilable/arithmetic_expressions1.rs28
2 files changed, 82 insertions, 1 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index c47e0ec..419b911 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -367,8 +367,61 @@ public:
{
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
+ auto combined = lhs->combine (rhs);
- infered = lhs->combine (rhs);
+ // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
+ switch (expr.get_expr_type ())
+ {
+ // integers or floats
+ case HIR::ArithmeticOrLogicalExpr::ADD:
+ case HIR::ArithmeticOrLogicalExpr::SUBTRACT:
+ case HIR::ArithmeticOrLogicalExpr::MULTIPLY:
+ case HIR::ArithmeticOrLogicalExpr::DIVIDE:
+ case HIR::ArithmeticOrLogicalExpr::MODULUS: {
+ bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
+ || (combined->get_kind () == TyTy::TypeKind::UINT)
+ || (combined->get_kind () == TyTy::TypeKind::FLOAT);
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (), "cannot apply operator to %s",
+ combined->as_string ().c_str ());
+ return;
+ }
+ }
+ break;
+
+ // integers or bools
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_AND:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_OR:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR: {
+ bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
+ || (combined->get_kind () == TyTy::TypeKind::UINT)
+ || (combined->get_kind () == TyTy::TypeKind::BOOL);
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (), "cannot apply operator to %s",
+ combined->as_string ().c_str ());
+ return;
+ }
+ }
+ break;
+
+ // integers only
+ case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
+ case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT: {
+ bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
+ || (combined->get_kind () == TyTy::TypeKind::UINT);
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (), "cannot apply operator to %s",
+ combined->as_string ().c_str ());
+ return;
+ }
+ }
+ break;
+ }
+
+ infered = combined;
}
void visit (HIR::ComparisonExpr &expr)
diff --git a/gcc/testsuite/rust.test/compilable/arithmetic_expressions1.rs b/gcc/testsuite/rust.test/compilable/arithmetic_expressions1.rs
new file mode 100644
index 0000000..efc63f5
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/arithmetic_expressions1.rs
@@ -0,0 +1,28 @@
+fn main() {
+ let a: i32 = 1;
+ let b: f32 = 5f32;
+ let c: bool = true;
+
+ let a1: i32 = a + 1;
+ let a2: i32 = a - 2;
+ let a3: i32 = a * 3;
+ let a4: i32 = a / 4;
+ let a5: i32 = a % 5;
+
+ let b1: f32 = b + 1f32;
+ let b2: f32 = b - 2f32;
+ let b3: f32 = b * 3f32;
+ let b4: f32 = b / 4f32;
+ // let b5: f32 = b % 5f32;
+
+ let aa1: i32 = a & 1;
+ let aa2: i32 = a | 2;
+ let aa2: i32 = a ^ 3;
+
+ let c1: bool = c & true;
+ let c2: bool = c | false;
+ let c3: bool = c ^ true;
+
+ let aaa1: i32 = a << 1;
+ let aaa2: i32 = a >> 2;
+}