diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-02 19:27:37 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-03 10:38:13 +0000 |
commit | 9abf0733814c5e4131b96afb1c0abad68f4cf4ef (patch) | |
tree | 1f37be267944d69e0de385c57c16bd9d077525cc | |
parent | 419677348e1c1e6092e74f55b3a7326a595d6114 (diff) | |
download | gcc-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.h | 133 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 9 |
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 (); |