On Tue, 1 Mar 2022, H.J. Lu wrote: > Use C++ RAII with make_temp_override in the C++ FE to automatically clear > currently_expanding_gimple_stmt.
Hmm, the temp-override isn't really a good fit since we only want to have the cleanup part and that should always "restore" to nullptr. Richard. > gcc/ > > PR middle-end/104721 > * cfgexpand.cc (expand_gimple_basic_block): Use make_temp_override > to clear currently_expanding_gimple_stmt automatically. > * tree.h (temp_override): Moved from cp/cp-tree.h. > (type_identity_t): Likewise. > make_temp_override(): Likewise. > > gcc/cp/ > > PR middle-end/104721 > * cp-tree.h (temp_override): Moved to ../tree.h. > (type_identity_t): Likewise. > make_temp_override(): Likewise. > --- > gcc/cfgexpand.cc | 15 +++++--------- > gcc/cp/cp-tree.h | 51 ------------------------------------------------ > gcc/tree.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 56 insertions(+), 61 deletions(-) > > diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc > index 87536ec7ccd..3d656113df5 100644 > --- a/gcc/cfgexpand.cc > +++ b/gcc/cfgexpand.cc > @@ -5817,6 +5817,9 @@ expand_gimple_basic_block (basic_block bb, bool > disable_tail_calls) > if (note) > NOTE_BASIC_BLOCK (note) = bb; > > + auto cleanup = make_temp_override (currently_expanding_gimple_stmt, > + nullptr); > + > for (; !gsi_end_p (gsi); gsi_next (&gsi)) > { > basic_block new_bb; > @@ -5927,10 +5930,7 @@ expand_gimple_basic_block (basic_block bb, bool > disable_tail_calls) > { > new_bb = expand_gimple_cond (bb, as_a <gcond *> (stmt)); > if (new_bb) > - { > - currently_expanding_gimple_stmt = NULL; > - return new_bb; > - } > + return new_bb; > } > else if (is_gimple_debug (stmt)) > { > @@ -6052,10 +6052,7 @@ expand_gimple_basic_block (basic_block bb, bool > disable_tail_calls) > if (can_fallthru) > bb = new_bb; > else > - { > - currently_expanding_gimple_stmt = NULL; > - return new_bb; > - } > + return new_bb; > } > } > else > @@ -6078,8 +6075,6 @@ expand_gimple_basic_block (basic_block bb, bool > disable_tail_calls) > } > } > > - currently_expanding_gimple_stmt = NULL; > - > /* Expand implicit goto and convert goto_locus. */ > FOR_EACH_EDGE (e, ei, bb->succs) > { > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 80994e94793..0a55588dc5d 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -1961,57 +1961,6 @@ public: > } > }; > > -/* RAII sentinel that saves the value of a variable, optionally > - overrides it right away, and restores its value when the sentinel > - id destructed. */ > - > -template <typename T> > -class temp_override > -{ > - T& overridden_variable; > - T saved_value; > -public: > - temp_override(T& var) : overridden_variable (var), saved_value (var) {} > - temp_override(T& var, T overrider) > - : overridden_variable (var), saved_value (var) > - { > - overridden_variable = overrider; > - } > - ~temp_override() { overridden_variable = saved_value; } > -}; > - > -/* Wrapping a template parameter in type_identity_t hides it from template > - argument deduction. */ > -#if __cpp_lib_type_identity > -using std::type_identity_t; > -#else > -template <typename T> > -struct type_identity { typedef T type; }; > -template <typename T> > -using type_identity_t = typename type_identity<T>::type; > -#endif > - > -/* Object generator function for temp_override, so you don't need to write > the > - type of the object as a template argument. > - > - Use as auto x = make_temp_override (flag); */ > - > -template <typename T> > -inline temp_override<T> > -make_temp_override (T& var) > -{ > - return { var }; > -} > - > -/* Likewise, but use as auto x = make_temp_override (flag, value); */ > - > -template <typename T> > -inline temp_override<T> > -make_temp_override (T& var, type_identity_t<T> overrider) > -{ > - return { var, overrider }; > -} > - > /* The cached class binding level, from the most recently exited > class, or NULL if none. */ > > diff --git a/gcc/tree.h b/gcc/tree.h > index 36ceed57064..32d610474d2 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -6581,4 +6581,55 @@ extern tree get_attr_nonstring_decl (tree, tree * = > NULL); > > extern int get_target_clone_attr_len (tree); > > +/* RAII sentinel that saves the value of a variable, optionally > + overrides it right away, and restores its value when the sentinel > + id destructed. */ > + > +template <typename T> > +class temp_override > +{ > + T& overridden_variable; > + T saved_value; > +public: > + temp_override(T& var) : overridden_variable (var), saved_value (var) {} > + temp_override(T& var, T overrider) > + : overridden_variable (var), saved_value (var) > + { > + overridden_variable = overrider; > + } > + ~temp_override() { overridden_variable = saved_value; } > +}; > + > +/* Wrapping a template parameter in type_identity_t hides it from template > + argument deduction. */ > +#if __cpp_lib_type_identity > +using std::type_identity_t; > +#else > +template <typename T> > +struct type_identity { typedef T type; }; > +template <typename T> > +using type_identity_t = typename type_identity<T>::type; > +#endif > + > +/* Object generator function for temp_override, so you don't need to write > the > + type of the object as a template argument. > + > + Use as auto x = make_temp_override (flag); */ > + > +template <typename T> > +inline temp_override<T> > +make_temp_override (T& var) > +{ > + return { var }; > +} > + > +/* Likewise, but use as auto x = make_temp_override (flag, value); */ > + > +template <typename T> > +inline temp_override<T> > +make_temp_override (T& var, type_identity_t<T> overrider) > +{ > + return { var, overrider }; > +} > + > #endif /* GCC_TREE_H */ > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)