diff mbox series

c++: replace in_template_function

Message ID 20230602151534.2132668-1-ppalka@redhat.com
State New
Headers show
Series c++: replace in_template_function | expand

Commit Message

Patrick Palka June 2, 2023, 3:15 p.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?

-- >8 --

All uses of in_template_function besides the one in cp_make_fname_decl
seem like they could be generalized to apply to all template contexts,
not just function templates.  To that end this patch replaces the
predicate with a cheaper and more general in_template_context predicate
that returns true for all template contexts.  If we legitimately need
to consider only function template contexts, as in cp_make_fname_decl,
we can just additionallly check e.g. current_function_decl.

One concrete benefit of this is that we no longer instantiate/odr-use
entities based on uses within a non-function template such as in the
adjusted testcase below.

gcc/cp/ChangeLog:

	* class.cc (build_base_path): Check in_template_context instead
	of in_template_function.
	(resolves_to_fixed_type_p): Likewise.
	* cp-tree.h (in_template_context): Define.
	(in_template_function): Remove.
	* decl.cc (cp_make_fname_decl): Check current_function_decl
	and in_template_context instead of in_template_function.
	* decl2.cc (mark_used): Check in_template_context instead of
	in_template_function.
	* pt.cc (in_template_function): Remove.
	* semantics.cc (enforce_access): Check in_template_context
	instead of current_template_parms directly.

gcc/testsuite/ChangeLog:

	* g++.dg/warn/Waddress-of-packed-member2.C: No longer expect a()
	to be marked as odr-used.
---
 gcc/cp/class.cc                               |  4 ++--
 gcc/cp/cp-tree.h                              |  2 +-
 gcc/cp/decl.cc                                |  2 +-
 gcc/cp/decl2.cc                               |  2 +-
 gcc/cp/pt.cc                                  | 19 -------------------
 gcc/cp/semantics.cc                           |  2 +-
 .../g++.dg/warn/Waddress-of-packed-member2.C  |  2 +-
 7 files changed, 7 insertions(+), 26 deletions(-)

Comments

Jason Merrill June 2, 2023, 4:30 p.m. UTC | #1
On 6/2/23 11:15, Patrick Palka wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?

OK.

> -- >8 --
> 
> All uses of in_template_function besides the one in cp_make_fname_decl
> seem like they could be generalized to apply to all template contexts,
> not just function templates.  To that end this patch replaces the
> predicate with a cheaper and more general in_template_context predicate
> that returns true for all template contexts.  If we legitimately need
> to consider only function template contexts, as in cp_make_fname_decl,
> we can just additionallly check e.g. current_function_decl.
> 
> One concrete benefit of this is that we no longer instantiate/odr-use
> entities based on uses within a non-function template such as in the
> adjusted testcase below.
> 
> gcc/cp/ChangeLog:
> 
> 	* class.cc (build_base_path): Check in_template_context instead
> 	of in_template_function.
> 	(resolves_to_fixed_type_p): Likewise.
> 	* cp-tree.h (in_template_context): Define.
> 	(in_template_function): Remove.
> 	* decl.cc (cp_make_fname_decl): Check current_function_decl
> 	and in_template_context instead of in_template_function.
> 	* decl2.cc (mark_used): Check in_template_context instead of
> 	in_template_function.
> 	* pt.cc (in_template_function): Remove.
> 	* semantics.cc (enforce_access): Check in_template_context
> 	instead of current_template_parms directly.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/warn/Waddress-of-packed-member2.C: No longer expect a()
> 	to be marked as odr-used.
> ---
>   gcc/cp/class.cc                               |  4 ++--
>   gcc/cp/cp-tree.h                              |  2 +-
>   gcc/cp/decl.cc                                |  2 +-
>   gcc/cp/decl2.cc                               |  2 +-
>   gcc/cp/pt.cc                                  | 19 -------------------
>   gcc/cp/semantics.cc                           |  2 +-
>   .../g++.dg/warn/Waddress-of-packed-member2.C  |  2 +-
>   7 files changed, 7 insertions(+), 26 deletions(-)
> 
> diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
> index bc84f4f731a..778759237dc 100644
> --- a/gcc/cp/class.cc
> +++ b/gcc/cp/class.cc
> @@ -344,7 +344,7 @@ build_base_path (enum tree_code code,
>   
>     bool uneval = (cp_unevaluated_operand != 0
>   		 || processing_template_decl
> -		 || in_template_function ());
> +		 || in_template_context);
>   
>     /* For a non-pointer simple base reference, express it as a COMPONENT_REF
>        without taking its address (and so causing lambda capture, 91933).  */
> @@ -8055,7 +8055,7 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
>     /* processing_template_decl can be false in a template if we're in
>        instantiate_non_dependent_expr, but we still want to suppress
>        this check.  */
> -  if (in_template_function ())
> +  if (in_template_context)
>       {
>         /* In a template we only care about the type of the result.  */
>         if (nonnull)
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index a1b882f11fe..ce2095c7aaa 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -1924,6 +1924,7 @@ extern GTY(()) struct saved_scope *scope_chain;
>   #define current_template_parms scope_chain->template_parms
>   #define current_template_depth \
>     (current_template_parms ? TMPL_PARMS_DEPTH (current_template_parms) : 0)
> +#define in_template_context (current_template_parms != NULL_TREE)
>   
>   #define processing_template_decl scope_chain->x_processing_template_decl
>   #define processing_specialization scope_chain->x_processing_specialization
> @@ -7353,7 +7354,6 @@ extern tree lookup_template_variable		(tree, tree);
>   extern bool uses_template_parms			(tree);
>   extern bool uses_template_parms_level		(tree, int);
>   extern bool uses_outer_template_parms_in_constraints (tree);
> -extern bool in_template_function		(void);
>   extern bool need_generic_capture		(void);
>   extern tree instantiate_class_template		(tree);
>   extern tree instantiate_template		(tree, tree, tsubst_flags_t);
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index a672e4844f1..3985c6d2d1f 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -5021,7 +5021,7 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
>     tree domain = NULL_TREE;
>     tree init = NULL_TREE;
>   
> -  if (!(type_dep && in_template_function ()))
> +  if (!(type_dep && current_function_decl && in_template_context))
>       {
>         const char *name = NULL;
>         bool release_name = false;
> diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
> index b510cdac554..b402befba6d 100644
> --- a/gcc/cp/decl2.cc
> +++ b/gcc/cp/decl2.cc
> @@ -5782,7 +5782,7 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
>   	  && DECL_OMP_DECLARE_REDUCTION_P (decl)))
>       maybe_instantiate_decl (decl);
>   
> -  if (processing_template_decl || in_template_function ())
> +  if (processing_template_decl || in_template_context)
>       return true;
>   
>     /* Check this too in case we're within instantiate_non_dependent_expr.  */
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 7fb3e75bceb..244b0b03454 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -10951,25 +10951,6 @@ uses_template_parms (tree t)
>       return instantiation_dependent_expression_p (t);
>   }
>   
> -/* Returns true iff we're processing an incompletely instantiated function
> -   template.  Useful instead of processing_template_decl because the latter
> -   is set to 0 during instantiate_non_dependent_expr.  */
> -
> -bool
> -in_template_function (void)
> -{
> -  /* Inspect the less volatile cfun->decl instead of current_function_decl;
> -     the latter might get set for e.g. access checking during satisfaction.  */
> -  tree fn = cfun ? cfun->decl : NULL_TREE;
> -  bool ret;
> -  ++processing_template_decl;
> -  ret = (fn && DECL_LANG_SPECIFIC (fn)
> -	 && DECL_TEMPLATE_INFO (fn)
> -	 && any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
> -  --processing_template_decl;
> -  return ret;
> -}
> -
>   /* Returns true if T depends on any template parameter with level LEVEL.  */
>   
>   bool
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 05df6282302..0843b5eae73 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -346,7 +346,7 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl,
>       }
>   
>     tree cs = current_scope ();
> -  if (current_template_parms
> +  if (in_template_context
>         && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
>       if (tree template_info = get_template_info (cs))
>         {
> diff --git a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
> index e9bf7cac04c..d619b28cfe1 100644
> --- a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
> +++ b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
> @@ -1,7 +1,7 @@
>   // PR c++/89973
>   // { dg-do compile { target c++14 } }
>   
> -constexpr int a(); // { dg-warning "used but never defined" }
> +constexpr int a();
>   
>   template <typename>
>   constexpr void *b = a(); // { dg-error "invalid conversion" }
diff mbox series

Patch

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index bc84f4f731a..778759237dc 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -344,7 +344,7 @@  build_base_path (enum tree_code code,
 
   bool uneval = (cp_unevaluated_operand != 0
 		 || processing_template_decl
-		 || in_template_function ());
+		 || in_template_context);
 
   /* For a non-pointer simple base reference, express it as a COMPONENT_REF
      without taking its address (and so causing lambda capture, 91933).  */
@@ -8055,7 +8055,7 @@  resolves_to_fixed_type_p (tree instance, int* nonnull)
   /* processing_template_decl can be false in a template if we're in
      instantiate_non_dependent_expr, but we still want to suppress
      this check.  */
-  if (in_template_function ())
+  if (in_template_context)
     {
       /* In a template we only care about the type of the result.  */
       if (nonnull)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a1b882f11fe..ce2095c7aaa 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1924,6 +1924,7 @@  extern GTY(()) struct saved_scope *scope_chain;
 #define current_template_parms scope_chain->template_parms
 #define current_template_depth \
   (current_template_parms ? TMPL_PARMS_DEPTH (current_template_parms) : 0)
+#define in_template_context (current_template_parms != NULL_TREE)
 
 #define processing_template_decl scope_chain->x_processing_template_decl
 #define processing_specialization scope_chain->x_processing_specialization
@@ -7353,7 +7354,6 @@  extern tree lookup_template_variable		(tree, tree);
 extern bool uses_template_parms			(tree);
 extern bool uses_template_parms_level		(tree, int);
 extern bool uses_outer_template_parms_in_constraints (tree);
-extern bool in_template_function		(void);
 extern bool need_generic_capture		(void);
 extern tree instantiate_class_template		(tree);
 extern tree instantiate_template		(tree, tree, tsubst_flags_t);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index a672e4844f1..3985c6d2d1f 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -5021,7 +5021,7 @@  cp_make_fname_decl (location_t loc, tree id, int type_dep)
   tree domain = NULL_TREE;
   tree init = NULL_TREE;
 
-  if (!(type_dep && in_template_function ()))
+  if (!(type_dep && current_function_decl && in_template_context))
     {
       const char *name = NULL;
       bool release_name = false;
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index b510cdac554..b402befba6d 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5782,7 +5782,7 @@  mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
 	  && DECL_OMP_DECLARE_REDUCTION_P (decl)))
     maybe_instantiate_decl (decl);
 
-  if (processing_template_decl || in_template_function ())
+  if (processing_template_decl || in_template_context)
     return true;
 
   /* Check this too in case we're within instantiate_non_dependent_expr.  */
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7fb3e75bceb..244b0b03454 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -10951,25 +10951,6 @@  uses_template_parms (tree t)
     return instantiation_dependent_expression_p (t);
 }
 
-/* Returns true iff we're processing an incompletely instantiated function
-   template.  Useful instead of processing_template_decl because the latter
-   is set to 0 during instantiate_non_dependent_expr.  */
-
-bool
-in_template_function (void)
-{
-  /* Inspect the less volatile cfun->decl instead of current_function_decl;
-     the latter might get set for e.g. access checking during satisfaction.  */
-  tree fn = cfun ? cfun->decl : NULL_TREE;
-  bool ret;
-  ++processing_template_decl;
-  ret = (fn && DECL_LANG_SPECIFIC (fn)
-	 && DECL_TEMPLATE_INFO (fn)
-	 && any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
-  --processing_template_decl;
-  return ret;
-}
-
 /* Returns true if T depends on any template parameter with level LEVEL.  */
 
 bool
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 05df6282302..0843b5eae73 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -346,7 +346,7 @@  enforce_access (tree basetype_path, tree decl, tree diag_decl,
     }
 
   tree cs = current_scope ();
-  if (current_template_parms
+  if (in_template_context
       && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
     if (tree template_info = get_template_info (cs))
       {
diff --git a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
index e9bf7cac04c..d619b28cfe1 100644
--- a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
+++ b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
@@ -1,7 +1,7 @@ 
 // PR c++/89973
 // { dg-do compile { target c++14 } }
 
-constexpr int a(); // { dg-warning "used but never defined" }
+constexpr int a();
 
 template <typename>
 constexpr void *b = a(); // { dg-error "invalid conversion" }