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

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).