mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
gccrs: unsafe: check use of target_feature attribute
The `target_feature` attribute is for conditional compilation and may or may not compile on all platforms. Using it requires an unsafe function or block. gcc/rust/ChangeLog: * checks/errors/rust-unsafe-checker.cc (check_target_attr): New function. (UnsafeChecker::check_function_attr): Call into `check_target_attr`. (UnsafeChecker::visit): Check for target_feature attributes. * checks/errors/rust-unsafe-checker.h: Add declarations. * util/rust-attributes.cc: Add attribute. gcc/testsuite/ChangeLog: * rust/compile/unsafe11.rs: New test. Signed-off-by: Prajwal S N <prajwalnadig21@gmail.com>
This commit is contained in:
committed by
Arthur Cohen
parent
f66b135d0b
commit
776ff05380
@@ -179,6 +179,31 @@ UnsafeChecker::check_function_call (HirId node_id, Location locus)
|
||||
locus);
|
||||
}
|
||||
|
||||
static void
|
||||
check_target_attr (HIR::Function *fn, Location locus)
|
||||
{
|
||||
if (std::any_of (fn->get_outer_attrs ().begin (),
|
||||
fn->get_outer_attrs ().end (),
|
||||
[] (const AST::Attribute &attr) {
|
||||
return attr.get_path ().as_string () == "target_feature";
|
||||
}))
|
||||
rust_error_at (locus,
|
||||
"call to function with %<#[target_feature]%> requires "
|
||||
"unsafe function or block");
|
||||
}
|
||||
|
||||
void
|
||||
UnsafeChecker::check_function_attr (HirId node_id, Location locus)
|
||||
{
|
||||
if (unsafe_context.is_in_context ())
|
||||
return;
|
||||
|
||||
auto maybe_fn = mappings.lookup_hir_item (node_id);
|
||||
|
||||
if (maybe_fn && maybe_fn->get_item_kind () == Item::ItemKind::Function)
|
||||
check_target_attr (static_cast<Function *> (maybe_fn), locus);
|
||||
}
|
||||
|
||||
void
|
||||
UnsafeChecker::visit (Lifetime &)
|
||||
{}
|
||||
@@ -398,11 +423,13 @@ UnsafeChecker::visit (CallExpr &expr)
|
||||
|
||||
rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
|
||||
|
||||
// At this point we have the function's HIR Id. There are two checks we
|
||||
// At this point we have the function's HIR Id. There are three checks we
|
||||
// must perform:
|
||||
// 1. The function is an unsafe one
|
||||
// 2. The function is an extern one
|
||||
// 3. The function is marked with a target_feature attribute
|
||||
check_function_call (definition_id, expr.get_locus ());
|
||||
check_function_attr (definition_id, expr.get_locus ());
|
||||
|
||||
if (expr.has_params ())
|
||||
for (auto &arg : expr.get_arguments ())
|
||||
|
||||
@@ -46,6 +46,11 @@ private:
|
||||
*/
|
||||
void check_function_call (HirId node_id, Location locus);
|
||||
|
||||
/**
|
||||
* Check if any unsafe attributes are present on a function
|
||||
*/
|
||||
void check_function_attr (HirId node_id, Location locus);
|
||||
|
||||
StackedContexts<HirId> unsafe_context;
|
||||
|
||||
Resolver::TypeCheckContext &context;
|
||||
|
||||
@@ -41,6 +41,9 @@ static const BuiltinAttrDefinition __definitions[]
|
||||
{"repr", CODE_GENERATION},
|
||||
{"path", EXPANSION},
|
||||
{"macro_use", NAME_RESOLUTION},
|
||||
// FIXME: This is not implemented yet, see
|
||||
// https://github.com/Rust-GCC/gccrs/issues/1475
|
||||
{"target_feature", CODE_GENERATION},
|
||||
// From now on, these are reserved by the compiler and gated through
|
||||
// #![feature(rustc_attrs)]
|
||||
{"rustc_inherit_overflow_checks", CODE_GENERATION}};
|
||||
|
||||
8
gcc/testsuite/rust/compile/unsafe11.rs
Normal file
8
gcc/testsuite/rust/compile/unsafe11.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
#[target_feature(sse)]
|
||||
fn foo() {
|
||||
let a: usize = 0;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo() // { dg-error "requires unsafe function or block" }
|
||||
}
|
||||
Reference in New Issue
Block a user