aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-08-03 17:24:14 +0200
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2023-08-11 13:32:52 +0000
commit969439fa8e9a2c5b49ce6086401cb39ad004307b (patch)
tree295215a3bf50a4427de925ad311fb7f2016f2ba0 /gcc
parent5712d7d383b0597cd00466e5995c1e620c2fc809 (diff)
downloadgcc-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.cc5
-rw-r--r--gcc/rust/expand/rust-macro-expand.h16
-rw-r--r--gcc/rust/rust-session-manager.cc6
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 ());