diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-04-04 16:35:13 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2025-04-16 09:04:47 +0000 |
commit | 5ac41dce35b947f5d1f904b39958ebf6f1b538cf (patch) | |
tree | 3612e5900e004cf5f97e38857b7fc694cab8c7a7 | |
parent | daf5dbc0272d57b772d579233268545c3a485e18 (diff) | |
download | gcc-5ac41dce35b947f5d1f904b39958ebf6f1b538cf.zip gcc-5ac41dce35b947f5d1f904b39958ebf6f1b538cf.tar.gz gcc-5ac41dce35b947f5d1f904b39958ebf6f1b538cf.tar.bz2 |
gccrs: Fix segv in unsafe chcker
Trait constants were missing type resolution step, this adds that
as if it was a normal constant. The unsafe checker was missing a
null check.
Fixes Rust-GCC#3612
gcc/rust/ChangeLog:
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): add null check
* hir/tree/rust-hir-item.h: add has_type helper
* typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item):
add missing type checking
gcc/testsuite/ChangeLog:
* rust/compile/issue-3612.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r-- | gcc/rust/checks/errors/rust-unsafe-checker.cc | 5 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 21 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3612.rs | 7 |
4 files changed, 34 insertions, 1 deletions
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index df775b2..41e851e 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -481,9 +481,14 @@ UnsafeChecker::visit (MethodCallExpr &expr) TyTy::BaseType *method_type; context.lookup_type (expr.get_method_name ().get_mappings ().get_hirid (), &method_type); + if (!method_type || !method_type->is<TyTy::FnType> ()) + return; auto &fn = static_cast<TyTy::FnType &> (*method_type); + // FIXME + // should probably use the defid lookup instead + // tl::optional<HIR::Item *> lookup_defid (DefId id); auto method = mappings.lookup_hir_implitem (fn.get_ref ()); if (!unsafe_context.is_in_context () && method) check_unsafe_call (static_cast<Function *> (method->first), diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index f45d743..41ba38c 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -2070,6 +2070,8 @@ public: Identifier get_name () const { return name; } + bool has_type () const { return expr != nullptr; } + bool has_expr () const { return expr != nullptr; } Type &get_type () diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 1492839..637fa8a 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -384,7 +384,26 @@ TraitItemReference::resolve_item (HIR::TraitItemType &type) void TraitItemReference::resolve_item (HIR::TraitItemConst &constant) { - // TODO + TyTy::BaseType *ty = nullptr; + if (constant.has_type ()) + ty = TypeCheckType::Resolve (constant.get_type ()); + + TyTy::BaseType *expr = nullptr; + if (constant.has_expr ()) + expr = TypeCheckExpr::Resolve (constant.get_expr ()); + + bool have_specified_ty = ty != nullptr && !ty->is<TyTy::ErrorType> (); + bool have_expr_ty = expr != nullptr && !expr->is<TyTy::ErrorType> (); + + if (have_specified_ty && have_expr_ty) + { + coercion_site (constant.get_mappings ().get_hirid (), + TyTy::TyWithLocation (ty, + constant.get_type ().get_locus ()), + TyTy::TyWithLocation (expr, + constant.get_expr ().get_locus ()), + constant.get_locus ()); + } } void diff --git a/gcc/testsuite/rust/compile/issue-3612.rs b/gcc/testsuite/rust/compile/issue-3612.rs new file mode 100644 index 0000000..5256d0a --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3612.rs @@ -0,0 +1,7 @@ +trait _St1 { + pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; + // { dg-error "no method named .as_ptr. found in the current scope .E0599." "" { target *-*-* } .-1 } + // { dg-error "failed to resolve receiver in MethodCallExpr" "" { target *-*-* } .-2 } +} + +fn main() {} |