Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion gcc/rust/expand/rust-macro-expand.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
{
// ensure that both invocation and rules are in a valid state
rust_assert (!invoc.is_marked_for_strip ());
rust_assert (!rules_def.is_marked_for_strip ());
/* Note: We can't safely check if rules_def is marked for strip here because
* rules_def might be a dangling pointer to a deleted macro definition.
* This can happen when a macro definition has an invalid attribute (such as
* #[x] where x is not an attribute macro), causing the item to be deleted
* during attribute processing, but the pointer in in the invocation map still
* exists.
*/
// rust_assert (!rules_def.is_marked_for_strip ());
rust_assert (rules_def.get_macro_rules ().size () > 0);
Comment on lines -43 to 51
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should prevent rules_def from becoming a dangling pointer (somehow). Maybe by delaying the insertion of names corresponding to macro rules definitions into namespaces until after attributes on the definitions have been processed?


/* probably something here about parsing invoc and rules def token trees to
Expand Down Expand Up @@ -314,6 +321,9 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc,

auto rdef = rules_def.value ();

if (!rdef)
return;

// We store the last expanded invocation and macro definition for error
// reporting in case the recursion limit is reached
last_invoc = *invoc.clone_macro_invocation_impl ();
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/util/rust-hir-map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,10 @@ Mappings::insert_macro_invocation (AST::MacroInvocation &invoc,
auto it = macroInvocations.find (invoc.get_macro_node_id ());
rust_assert (it == macroInvocations.end ());

// Don't insert null pointers into the map as it could segfault later
if (!def)
return;

macroInvocations[invoc.get_macro_node_id ()] = def;
}

Expand Down
29 changes: 29 additions & 0 deletions gcc/testsuite/rust/compile/issue-4187-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
macro x(
$macro_name:ident,
$macro2_name:ident,
$type_name:ident,
$field_name:ident,
$const_name:ident
) {
pub struct $type_name {}

pub const $const_name: $type_name = $type_name {};

#[x]
// { dg-error "macro not found" "" { target *-*-* } .-1 }
macro_rules! $macro_name {
() => {};
}

pub macro $type_name {
(Copy $e:expr) => {},
() => {;},

}
}

x!(test_fields, test_fields2, x, field, MY_CONST);

pub fn check_fields_local() {
test_fields!(check_fields); // { dg-error "Failed to match any rule within macro" }
}
32 changes: 32 additions & 0 deletions gcc/testsuite/rust/compile/issue-4187-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
macro x(
$macro_name:ident,
$macro2_name:ident,
$type_name:ident,
$field_name:ident,
$const_name:ident
) {
pub struct $type_name {}

pub const $const_name: $type_name = $type_name {};

#[x]
// { dg-error "macro not found" "" { target *-*-* } .-1 }
macro_rules! $macro_name {
(check_fields) => {{
assert_eq!($const_name.field, Field::MacroCtxt);
}};
}

pub macro $type_name {
(Copy $e:expr) => {},
(check_fields) => {test_fields!(check_fields);},

}
}

x!(test_fields, test_fields2, x, field, MY_CONST);

pub fn check_fields_local() {
test_fields!(check_fields); // { dg-error "Failed to match any rule within macro" }

Check failure on line 30 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-and-check-asan

Test failure (FAIL)

(test for errors, line 30)

Check failure on line 30 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-alpine-32bit-and-check-alpine-32bit

Test failure (FAIL)

(test for errors, line 30)

Check failure on line 30 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-alpine-32bit-and-check-alpine-32bit

Test failure (FAIL)

(test for errors, line 30)

Check failure on line 30 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-and-check-asan

Test failure (FAIL)

(test for errors, line 30)
test_fields2!(check_fields); // { dg-error "could not resolve macro invocation" }

Check failure on line 31 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-and-check-asan

Test failure (FAIL)

(test for errors, line 31)

Check failure on line 31 in gcc/testsuite/rust/compile/issue-4187-2.rs

View workflow job for this annotation

GitHub Actions / build-and-check-asan

Test failure (FAIL)

(test for errors, line 31)
}
Loading