aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-19 17:02:45 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-20 10:03:50 +0000
commit85d8754632d597fe3d94404406082bcbb2f5ff94 (patch)
treea118c7d4e6c294fb2b775da8fb75efad6227b0f0 /gcc
parent6e09093f1f759a78387d214b6d0fe8ba17b752b6 (diff)
downloadgcc-85d8754632d597fe3d94404406082bcbb2f5ff94.zip
gcc-85d8754632d597fe3d94404406082bcbb2f5ff94.tar.gz
gcc-85d8754632d597fe3d94404406082bcbb2f5ff94.tar.bz2
Implement NegationExpression
This is an example of a unary expression in gimple. The rules for enforcing the types are observed in the type resolver here too. Unary negate cannot be applied to bools but only integers and floats. Unary not cannot be applied to floating points but can be applied to integers and bools.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h19
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h28
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h39
-rw-r--r--gcc/testsuite/rust.test/compilable/unary_operators.rs6
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/unary_negation.rs8
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/unary_not.rs8
7 files changed, 113 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index ff02d6b..da3c9cd 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -378,6 +378,25 @@ public:
expr.get_locus ());
}
+ void visit (HIR::NegationExpr &expr)
+ {
+ Operator op (OPERATOR_INVALID);
+ switch (expr.get_negation_type ())
+ {
+ case HIR::NegationExpr::NegationType::NEGATE:
+ op = OPERATOR_MINUS;
+ break;
+
+ case HIR::NegationExpr::NegationType::NOT:
+ op = OPERATOR_NOT;
+ break;
+ }
+
+ Bexpression *negated_expr = CompileExpr::Compile (expr.get_expr (), ctx);
+ translated = ctx->get_backend ()->unary_expression (op, negated_expr,
+ expr.get_locus ());
+ }
+
void visit (HIR::IfExpr &expr)
{
auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 6f872ab..a924ef2 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -504,6 +504,34 @@ public:
expr.get_locus ());
}
+ void visit (AST::NegationExpr &expr)
+ {
+ std::vector<HIR::Attribute> outer_attribs;
+
+ HIR::NegationExpr::NegationType type;
+ switch (expr.get_negation_type ())
+ {
+ case AST::NegationExpr::NegationType::NEGATE:
+ type = HIR::NegationExpr::NegationType::NEGATE;
+ break;
+ case AST::NegationExpr::NegationType::NOT:
+ type = HIR::NegationExpr::NegationType::NOT;
+ break;
+ }
+
+ HIR::Expr *negated_value
+ = ASTLoweringExpr::translate (expr.get_negated_expr ().get ());
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+ translated
+ = new HIR::NegationExpr (mapping,
+ std::unique_ptr<HIR::Expr> (negated_value), type,
+ std::move (outer_attribs), expr.get_locus ());
+ }
+
void visit (AST::StructExprStructFields &struct_expr)
{
std::vector<HIR::Attribute> inner_attribs;
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 181124a..03b3496 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -128,6 +128,11 @@ public:
ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
}
+ void visit (AST::NegationExpr &expr)
+ {
+ ResolveExpr::go (expr.get_negated_expr ().get (), expr.get_node_id ());
+ }
+
void visit (AST::IfExpr &expr)
{
ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 419b911..02830cd 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -456,6 +456,45 @@ public:
infered = lhs->combine (rhs);
}
+ void visit (HIR::NegationExpr &expr)
+ {
+ auto negated_expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
+
+ // https://doc.rust-lang.org/reference/expressions/operator-expr.html#negation-operators
+ switch (expr.get_negation_type ())
+ {
+ case HIR::NegationExpr::NegationType::NEGATE: {
+ bool valid
+ = (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::FLOAT);
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (), "cannot apply unary - to %s",
+ negated_expr_ty->as_string ().c_str ());
+ return;
+ }
+ }
+ break;
+
+ case HIR::NegationExpr::NegationType::NOT: {
+ bool valid
+ = (negated_expr_ty->get_kind () == TyTy::TypeKind::BOOL)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT);
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (), "cannot apply unary ! to %s",
+ negated_expr_ty->as_string ().c_str ());
+ return;
+ }
+ }
+ break;
+ }
+
+ infered = negated_expr_ty;
+ }
+
void visit (HIR::IfExpr &expr)
{
TypeCheckExpr::Resolve (expr.get_if_condition ());
diff --git a/gcc/testsuite/rust.test/compilable/unary_operators.rs b/gcc/testsuite/rust.test/compilable/unary_operators.rs
new file mode 100644
index 0000000..1ed9666
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/unary_operators.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let a: i32 = -1;
+ let b: i32 = 3 - -1;
+ let c: bool = !false;
+ let d: i32 = !3;
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/unary_negation.rs b/gcc/testsuite/rust.test/fail_compilation/unary_negation.rs
new file mode 100644
index 0000000..476b908
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/unary_negation.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let a: i32 = -1;
+ let b: i32 = 3 - -1;
+ let c: bool = !false;
+ let d: i32 = !3;
+
+ let e: f32 = -true;
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/unary_not.rs b/gcc/testsuite/rust.test/fail_compilation/unary_not.rs
new file mode 100644
index 0000000..f358f0e
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/unary_not.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let a: i32 = -1;
+ let b: i32 = 3 - -1;
+ let c: bool = !false;
+ let d: i32 = !3;
+
+ let e: f32 = !5f32;
+}