public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Avoid adding implicit attributes during apply_late_template_attributes [PR101180]
@ 2021-11-19 10:06 Jakub Jelinek
  2021-11-19 15:40 ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2021-11-19 10:06 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

decl_attributes and its caller cplus_decl_attributes sometimes add
implicit attributes, e.g. optimize attribute if #pragma GCC optimize
is active, target attribute if #pragma GCC target is active, or
e.g. omp declare target attribute if in between #pragma omp declare target
and #pragma omp end declare target.

For templates that seems highly undesirable to me though, they should
get those implicit attributes from the spot the templates were parsed
(and they do get that), then tsubst through copy_node copies those
attributes, but then apply_late_template_attributes can or does add
a new set from the spot where they are instantiated, which can be pretty
random point of first use of the template.

Consider e.g.
#pragma GCC push_options
#pragma GCC target "avx"
template <int N>
inline void foo ()
{
}
#pragma GCC pop_options
#pragma GCC push_options
#pragma GCC target "crc32"
void
bar ()
{
  foo<0> ();
}
#pragma GCC pop_options
testcase where the intention is that foo has avx target attribute
and bar has crc32 target attribute, but we end up with
__attribute__((target ("crc32"), target ("avx")))
on foo<0> (and due to yet another bug actually don't enable avx
in foo<0>).  In this particular case it is a regression caused
by r12-299-ga0fdff3cf33f7284 which apparently calls
cplus_decl_attributes even if attributes != NULL but late_attrs
is NULL, before those changes we didn't call it in those cases.
But, if there is at least one unrelated dependent attribute this
would happen already in older releases.

The following patch fixes that by temporarily overriding the variables
that control the addition of the implicit attributes.

Shall we also change the function so that it doesn't call
cplus_decl_attributes if late_attrs is NULL, or was that change
intentional?

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-11-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/101180
	* pt.c (apply_late_template_attributes): Temporarily override
	current_optimize_pragma, optimization_current_node,
	current_target_pragma and scope_chain->omp_declare_target_attribute,
	so that cplus_decl_attributes doesn't add implicit attributes.

	* g++.target/i386/pr101180.C: New test.

--- gcc/cp/pt.c.jj	2021-11-18 12:33:22.025628027 +0100
+++ gcc/cp/pt.c	2021-11-18 19:08:52.800539490 +0100
@@ -11722,6 +11722,17 @@ apply_late_template_attributes (tree *de
 	q = &TREE_CHAIN (*q);
     }
 
+  /* cplus_decl_attributes can add some attributes implicitly.  For templates,
+     those attributes should have been added already when those templates were
+     parsed, and shouldn't be added based on from which context they are
+     first time instantiated.  */
+  auto o1 = make_temp_override (current_optimize_pragma, NULL_TREE);
+  auto o2 = make_temp_override (optimization_current_node,
+				optimization_default_node);
+  auto o3 = make_temp_override (current_target_pragma, NULL_TREE);
+  auto o4 = make_temp_override (scope_chain->omp_declare_target_attribute,
+				NULL);
+
   cplus_decl_attributes (decl_p, late_attrs, attr_flags);
 
   return true;
--- gcc/testsuite/g++.target/i386/pr101180.C.jj	2021-11-18 19:11:50.512009888 +0100
+++ gcc/testsuite/g++.target/i386/pr101180.C	2021-11-18 19:11:33.066258216 +0100
@@ -0,0 +1,25 @@
+// PR c++/101180
+// { dg-do compile { target c++11 } }
+
+#pragma GCC target "avx"
+template <typename> struct A {};
+#pragma GCC push_options
+#pragma GCC target "avx,avx2,bmi,bmi2,fma,f16c"
+template <typename T> using B = A<T>;
+template <typename> struct C;
+template <> struct C<float> {
+  __attribute__((always_inline)) float operator()(long) { return .0f; }
+};
+long d;
+template <typename T> void e(B<T>) {
+  T{C<T>()(d)};
+}
+template <typename T, typename FromT> void f(T d, FromT) {
+  e(d);
+}
+int g;
+void h() {
+  A<float> i;
+  f(i, g);
+}
+#pragma GCC pop_options

	Jakub


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: Avoid adding implicit attributes during apply_late_template_attributes [PR101180]
  2021-11-19 10:06 [PATCH] c++: Avoid adding implicit attributes during apply_late_template_attributes [PR101180] Jakub Jelinek
@ 2021-11-19 15:40 ` Jason Merrill
  2021-11-24  8:16   ` [PATCH] c++: Return early in apply_late_template_attributes if there are no late attribs [PR101180] Jakub Jelinek
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2021-11-19 15:40 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On 11/19/21 05:06, Jakub Jelinek wrote:
> Hi!
> 
> decl_attributes and its caller cplus_decl_attributes sometimes add
> implicit attributes, e.g. optimize attribute if #pragma GCC optimize
> is active, target attribute if #pragma GCC target is active, or
> e.g. omp declare target attribute if in between #pragma omp declare target
> and #pragma omp end declare target.
> 
> For templates that seems highly undesirable to me though, they should
> get those implicit attributes from the spot the templates were parsed
> (and they do get that), then tsubst through copy_node copies those
> attributes, but then apply_late_template_attributes can or does add
> a new set from the spot where they are instantiated, which can be pretty
> random point of first use of the template.
> 
> Consider e.g.
> #pragma GCC push_options
> #pragma GCC target "avx"
> template <int N>
> inline void foo ()
> {
> }
> #pragma GCC pop_options
> #pragma GCC push_options
> #pragma GCC target "crc32"
> void
> bar ()
> {
>    foo<0> ();
> }
> #pragma GCC pop_options
> testcase where the intention is that foo has avx target attribute
> and bar has crc32 target attribute, but we end up with
> __attribute__((target ("crc32"), target ("avx")))
> on foo<0> (and due to yet another bug actually don't enable avx
> in foo<0>).  In this particular case it is a regression caused
> by r12-299-ga0fdff3cf33f7284 which apparently calls
> cplus_decl_attributes even if attributes != NULL but late_attrs
> is NULL, before those changes we didn't call it in those cases.
> But, if there is at least one unrelated dependent attribute this
> would happen already in older releases.
> 
> The following patch fixes that by temporarily overriding the variables
> that control the addition of the implicit attributes.

OK.

> Shall we also change the function so that it doesn't call
> cplus_decl_attributes if late_attrs is NULL [...]?

Please.

> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2021-11-19  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/101180
> 	* pt.c (apply_late_template_attributes): Temporarily override
> 	current_optimize_pragma, optimization_current_node,
> 	current_target_pragma and scope_chain->omp_declare_target_attribute,
> 	so that cplus_decl_attributes doesn't add implicit attributes.
> 
> 	* g++.target/i386/pr101180.C: New test.
> 
> --- gcc/cp/pt.c.jj	2021-11-18 12:33:22.025628027 +0100
> +++ gcc/cp/pt.c	2021-11-18 19:08:52.800539490 +0100
> @@ -11722,6 +11722,17 @@ apply_late_template_attributes (tree *de
>   	q = &TREE_CHAIN (*q);
>       }
>   
> +  /* cplus_decl_attributes can add some attributes implicitly.  For templates,
> +     those attributes should have been added already when those templates were
> +     parsed, and shouldn't be added based on from which context they are
> +     first time instantiated.  */
> +  auto o1 = make_temp_override (current_optimize_pragma, NULL_TREE);
> +  auto o2 = make_temp_override (optimization_current_node,
> +				optimization_default_node);
> +  auto o3 = make_temp_override (current_target_pragma, NULL_TREE);
> +  auto o4 = make_temp_override (scope_chain->omp_declare_target_attribute,
> +				NULL);
> +
>     cplus_decl_attributes (decl_p, late_attrs, attr_flags);
>   
>     return true;
> --- gcc/testsuite/g++.target/i386/pr101180.C.jj	2021-11-18 19:11:50.512009888 +0100
> +++ gcc/testsuite/g++.target/i386/pr101180.C	2021-11-18 19:11:33.066258216 +0100
> @@ -0,0 +1,25 @@
> +// PR c++/101180
> +// { dg-do compile { target c++11 } }
> +
> +#pragma GCC target "avx"
> +template <typename> struct A {};
> +#pragma GCC push_options
> +#pragma GCC target "avx,avx2,bmi,bmi2,fma,f16c"
> +template <typename T> using B = A<T>;
> +template <typename> struct C;
> +template <> struct C<float> {
> +  __attribute__((always_inline)) float operator()(long) { return .0f; }
> +};
> +long d;
> +template <typename T> void e(B<T>) {
> +  T{C<T>()(d)};
> +}
> +template <typename T, typename FromT> void f(T d, FromT) {
> +  e(d);
> +}
> +int g;
> +void h() {
> +  A<float> i;
> +  f(i, g);
> +}
> +#pragma GCC pop_options
> 
> 	Jakub
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] c++: Return early in apply_late_template_attributes if there are no late attribs [PR101180]
  2021-11-19 15:40 ` Jason Merrill
@ 2021-11-24  8:16   ` Jakub Jelinek
  2021-11-25  2:43     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2021-11-24  8:16 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On Fri, Nov 19, 2021 at 10:40:50AM -0500, Jason Merrill wrote:
> > Shall we also change the function so that it doesn't call
> > cplus_decl_attributes if late_attrs is NULL [...]?
> 
> Please.

Here it is.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-11-24  Jakub Jelinek  <jakub@redhat.com>

	PR c++/101180
	* pt.c (apply_late_template_attributes): Return early if there are no
	dependent attributes.

--- gcc/cp/pt.c.jj	2021-11-22 10:07:01.360225139 +0100
+++ gcc/cp/pt.c	2021-11-23 11:23:16.808321905 +0100
@@ -11712,6 +11712,9 @@ apply_late_template_attributes (tree *de
   /* Apply any non-dependent attributes.  */
   *p = nondep;
 
+  if (nondep == attributes)
+    return true;
+
   /* And then any dependent ones.  */
   tree late_attrs = NULL_TREE;
   tree *q = &late_attrs;


	Jakub


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: Return early in apply_late_template_attributes if there are no late attribs [PR101180]
  2021-11-24  8:16   ` [PATCH] c++: Return early in apply_late_template_attributes if there are no late attribs [PR101180] Jakub Jelinek
@ 2021-11-25  2:43     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2021-11-25  2:43 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On 11/24/21 03:16, Jakub Jelinek wrote:
> On Fri, Nov 19, 2021 at 10:40:50AM -0500, Jason Merrill wrote:
>>> Shall we also change the function so that it doesn't call
>>> cplus_decl_attributes if late_attrs is NULL [...]?
>>
>> Please.
> 
> Here it is.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2021-11-24  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/101180
> 	* pt.c (apply_late_template_attributes): Return early if there are no
> 	dependent attributes.
> 
> --- gcc/cp/pt.c.jj	2021-11-22 10:07:01.360225139 +0100
> +++ gcc/cp/pt.c	2021-11-23 11:23:16.808321905 +0100
> @@ -11712,6 +11712,9 @@ apply_late_template_attributes (tree *de
>     /* Apply any non-dependent attributes.  */
>     *p = nondep;
>   
> +  if (nondep == attributes)
> +    return true;
> +
>     /* And then any dependent ones.  */
>     tree late_attrs = NULL_TREE;
>     tree *q = &late_attrs;
> 
> 
> 	Jakub
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-11-25  2:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-19 10:06 [PATCH] c++: Avoid adding implicit attributes during apply_late_template_attributes [PR101180] Jakub Jelinek
2021-11-19 15:40 ` Jason Merrill
2021-11-24  8:16   ` [PATCH] c++: Return early in apply_late_template_attributes if there are no late attribs [PR101180] Jakub Jelinek
2021-11-25  2:43     ` 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).