* [PATCH] c++: replace in_template_function
@ 2023-06-02 15:15 Patrick Palka
2023-06-02 16:30 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Patrick Palka @ 2023-06-02 15:15 UTC (permalink / raw)
To: gcc-patches; +Cc: jason, Patrick Palka
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(-)
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" }
--
2.41.0.rc1.10.g9e49351c30
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] c++: replace in_template_function
2023-06-02 15:15 [PATCH] c++: replace in_template_function Patrick Palka
@ 2023-06-02 16:30 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2023-06-02 16:30 UTC (permalink / raw)
To: Patrick Palka, gcc-patches
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" }
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-06-02 16:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-02 15:15 [PATCH] c++: replace in_template_function Patrick Palka
2023-06-02 16:30 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).