aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-02 19:27:37 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-03 10:38:13 +0000
commit9abf0733814c5e4131b96afb1c0abad68f4cf4ef (patch)
tree1f37be267944d69e0de385c57c16bd9d077525cc
parent419677348e1c1e6092e74f55b3a7326a595d6114 (diff)
downloadgcc-9abf0733814c5e4131b96afb1c0abad68f4cf4ef.zip
gcc-9abf0733814c5e4131b96afb1c0abad68f4cf4ef.tar.gz
gcc-9abf0733814c5e4131b96afb1c0abad68f4cf4ef.tar.bz2
Fix type resolution null pointer crash
This also enhance ArithmeticOrLogicalExpr rules and associated error handling to propagate up the stack.
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h133
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc9
2 files changed, 73 insertions, 69 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 1df02d1..82977e4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -37,12 +37,7 @@ public:
expr->accept_vis (resolver);
if (resolver.infered == nullptr)
- {
- rust_error_at (expr->get_locus_slow (),
- "failed to resolve type for %s\n",
- expr->as_string ().c_str ());
- return nullptr;
- }
+ return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
auto ref = expr->get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
@@ -430,73 +425,19 @@ public:
{
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
- auto combined = lhs->combine (rhs);
- // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
- switch (expr.get_expr_type ())
+ bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
+ bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
+ bool valid = valid_lhs && valid_rhs;
+ if (!valid)
{
- // 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)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL))
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::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)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL));
- 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)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL));
- if (!valid)
- {
- rust_error_at (expr.get_locus (), "cannot apply operator to %s",
- combined->as_string ().c_str ());
- return;
- }
- }
- break;
+ rust_error_at (expr.get_locus (),
+ "cannot apply this operator to types %s and %s",
+ lhs->as_string ().c_str (), rhs->as_string ().c_str ());
+ return;
}
- infered = combined;
+ infered = lhs->combine (rhs);
infered->append_reference (lhs->get_ref ());
infered->append_reference (rhs->get_ref ());
}
@@ -596,7 +537,10 @@ public:
{
auto expected_ty = context->peek_return_type ();
infered = expected_ty->combine (blk_expr);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::IfExprConseqElse &expr)
@@ -635,7 +579,10 @@ public:
auto else_blk_combined = expected_ty->combine (else_block_tyty);
infered = if_blk_combined->combine (else_blk_combined);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::IfExprConseqIf &expr)
@@ -651,7 +598,10 @@ public:
infered = expected_ty->combine (if_blk);
infered = infered->combine (elif_blk);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::BlockExpr &expr);
@@ -806,6 +756,51 @@ private:
is_final_expr (is_final_expr)
{}
+ bool
+ validate_arithmetic_type (TyTy::TyBase *type,
+ HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
+ {
+ // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
+ // this will change later when traits are added
+ switch (expr_type)
+ {
+ case HIR::ArithmeticOrLogicalExpr::ADD:
+ case HIR::ArithmeticOrLogicalExpr::SUBTRACT:
+ case HIR::ArithmeticOrLogicalExpr::MULTIPLY:
+ case HIR::ArithmeticOrLogicalExpr::DIVIDE:
+ case HIR::ArithmeticOrLogicalExpr::MODULUS:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::FLOAT)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL))
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::FLOAT));
+
+ // integers or bools
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_AND:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_OR:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::BOOL)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
+
+ // integers only
+ case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
+ case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
+ }
+ }
+
TyTy::TyBase *infered;
TyTy::TyBase *infered_array_elems;
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 435af79..416cd89 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -23,6 +23,9 @@
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-struct-field.h"
+extern bool
+saw_errors (void);
+
namespace Rust {
namespace Resolver {
@@ -32,9 +35,15 @@ TypeResolution::Resolve (HIR::Crate &crate)
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
TypeCheckTopLevel::Resolve (it->get ());
+ if (saw_errors ())
+ return;
+
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
TypeCheckItem::Resolve (it->get ());
+ if (saw_errors ())
+ return;
+
auto mappings = Analysis::Mappings::get ();
auto context = TypeCheckContext::get ();