diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-19 17:29:10 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-20 10:02:41 +0000 |
commit | 6e09093f1f759a78387d214b6d0fe8ba17b752b6 (patch) | |
tree | 816f115416b052e671e77b8367d49e0ec767d9e1 /gcc | |
parent | 76b308af7e69f5b50fee96ba4b3584935e621259 (diff) | |
download | gcc-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.h | 55 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/arithmetic_expressions1.rs | 28 |
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; +} |