diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2023-08-03 17:24:14 +0200 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2023-08-11 13:32:52 +0000 |
commit | 969439fa8e9a2c5b49ce6086401cb39ad004307b (patch) | |
tree | 295215a3bf50a4427de925ad311fb7f2016f2ba0 /gcc | |
parent | 5712d7d383b0597cd00466e5995c1e620c2fc809 (diff) | |
download | gcc-969439fa8e9a2c5b49ce6086401cb39ad004307b.zip gcc-969439fa8e9a2c5b49ce6086401cb39ad004307b.tar.gz gcc-969439fa8e9a2c5b49ce6086401cb39ad004307b.tar.bz2 |
macro-expand: Keep optional references to last_{def, invoc}
This avoids a use-after-free when reaching the recursion limit.
gcc/rust/ChangeLog:
* expand/rust-macro-expand.h: Keep optional references for last_def
and last_invoc.
* expand/rust-macro-expand.cc (MacroExpander::expand_invoc): Store
optional references.
* rust-session-manager.cc (Session::expansion): Use tl::optional's APIs
for better checking.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 5 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 16 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 6 |
3 files changed, 18 insertions, 9 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 74a3e06..f0828f6 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -17,6 +17,7 @@ // <http://www.gnu.org/licenses/>. #include "rust-macro-expand.h" +#include "optional.h" #include "rust-macro-substitute-ctx.h" #include "rust-ast-full.h" #include "rust-ast-visitor.h" @@ -281,8 +282,8 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon) // We store the last expanded invocation and macro definition for error // reporting in case the recursion limit is reached - last_invoc = &invoc; - last_def = rules_def; + last_invoc = *invoc.clone_macro_invocation_impl (); + last_def = *rules_def; if (rules_def->is_builtin ()) fragment diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index 6564377..ac6abe4 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -19,6 +19,7 @@ #ifndef RUST_MACRO_EXPAND_H #define RUST_MACRO_EXPAND_H +#include "optional.h" #include "rust-buffered-queue.h" #include "rust-parse.h" #include "rust-token.h" @@ -480,8 +481,15 @@ struct MacroExpander */ void reset_changed_state () { has_changed_flag = false; } - AST::MacroRulesDefinition *get_last_definition () { return last_def; } - AST::MacroInvocation *get_last_invocation () { return last_invoc; } + tl::optional<AST::MacroRulesDefinition &> &get_last_definition () + { + return last_def; + } + + tl::optional<AST::MacroInvocation &> &get_last_invocation () + { + return last_invoc; + } private: AST::Fragment parse_proc_macro_output (ProcMacro::TokenStream ts); @@ -493,8 +501,8 @@ private: AST::Fragment expanded_fragment; bool has_changed_flag; - AST::MacroRulesDefinition *last_def; - AST::MacroInvocation *last_invoc; + tl::optional<AST::MacroRulesDefinition &> last_def; + tl::optional<AST::MacroInvocation &> last_invoc; public: Resolver::Resolver *resolver; diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index b860a32..18e7ea2 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -898,10 +898,10 @@ Session::expansion (AST::Crate &crate) if (iterations == cfg.recursion_limit) { - auto last_invoc = expander.get_last_invocation (); - auto last_def = expander.get_last_definition (); + auto &last_invoc = expander.get_last_invocation (); + auto &last_def = expander.get_last_definition (); - rust_assert (last_def && last_invoc); + rust_assert (last_def.has_value () && last_invoc.has_value ()); rich_location range (line_table, last_invoc->get_locus ()); range.add_range (last_def->get_locus ()); |