diff mbox

[C++,RFC] Fix up attribute handling in templates (PR c++/79502)

Message ID 20170215173018.GM1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 15, 2017, 5:30 p.m. UTC
On Wed, Feb 15, 2017 at 11:56:30AM -0500, Jason Merrill wrote:
> On Tue, Feb 14, 2017 at 3:13 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > The following testcase fails, because while we have the nodiscard
> > attribute on the template, we actually never propagate it to the
> > instantiation, which is where it is checked (I'm really surprised about
> > this).
> 
> Normally we propagate attributes when instantiating the class; see the
> call to apply_late_template_attributes in
> instantiate_class_template_1.  I'm not sure why that wouldn't be

Yes, instantiate_class_template_1 calls apply_late_template_attributes,
but that actually does nothing if there are no dependent attributes.
If there are any, it sets TYPE_ATTRIBUTES (or DECL_ATTRIBUTES) to
a copy of the attributes list, removes all the dependent attributes
from there and calls cplus_decl_attributes on the late attrs (after
tsubst_attribute them).  So setting {TYPE,DECL}_ATTRIBUTES to the
attributes list unmodified if there are no dependent ones matches
the behavior for non-dependent ones if there is at least one dependent.

So, does the following patch look better?

2017-02-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/79502
	* pt.c (apply_late_template_attributes): If there are
	no dependent attributes, set *p to attributes.

	* g++.dg/cpp1z/nodiscard4.C: New test.



	Jakub

Comments

Jason Merrill Feb. 15, 2017, 8:19 p.m. UTC | #1
OK.

On Wed, Feb 15, 2017 at 12:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Feb 15, 2017 at 11:56:30AM -0500, Jason Merrill wrote:
>> On Tue, Feb 14, 2017 at 3:13 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>> > The following testcase fails, because while we have the nodiscard
>> > attribute on the template, we actually never propagate it to the
>> > instantiation, which is where it is checked (I'm really surprised about
>> > this).
>>
>> Normally we propagate attributes when instantiating the class; see the
>> call to apply_late_template_attributes in
>> instantiate_class_template_1.  I'm not sure why that wouldn't be
>
> Yes, instantiate_class_template_1 calls apply_late_template_attributes,
> but that actually does nothing if there are no dependent attributes.
> If there are any, it sets TYPE_ATTRIBUTES (or DECL_ATTRIBUTES) to
> a copy of the attributes list, removes all the dependent attributes
> from there and calls cplus_decl_attributes on the late attrs (after
> tsubst_attribute them).  So setting {TYPE,DECL}_ATTRIBUTES to the
> attributes list unmodified if there are no dependent ones matches
> the behavior for non-dependent ones if there is at least one dependent.
>
> So, does the following patch look better?
>
> 2017-02-15  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/79502
>         * pt.c (apply_late_template_attributes): If there are
>         no dependent attributes, set *p to attributes.
>
>         * g++.dg/cpp1z/nodiscard4.C: New test.
>
> --- gcc/cp/pt.c.jj      2017-02-14 09:23:49.000000000 +0100
> +++ gcc/cp/pt.c 2017-02-15 18:21:45.581055915 +0100
> @@ -10113,6 +10113,8 @@ apply_late_template_attributes (tree *de
>
>        cplus_decl_attributes (decl_p, late_attrs, attr_flags);
>      }
> +  else
> +    *p = attributes;
>  }
>
>  /* Perform (or defer) access check for typedefs that were referenced
> --- gcc/testsuite/g++.dg/cpp1z/nodiscard4.C.jj  2017-02-15 18:11:33.281135469 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C     2017-02-15 18:11:33.281135469 +0100
> @@ -0,0 +1,14 @@
> +// PR c++/79502
> +// { dg-do compile { target c++11 } }
> +
> +template<typename>
> +struct [[nodiscard]] missiles {};
> +
> +missiles<void> make() { return {}; }
> +missiles<void> (*fnptr)() = make;
> +
> +int main()
> +{
> +  make();      // { dg-warning "ignoring returned value of type" }
> +  fnptr();     // { dg-warning "ignoring returned value of type" }
> +}
>
>
>         Jakub
diff mbox

Patch

--- gcc/cp/pt.c.jj	2017-02-14 09:23:49.000000000 +0100
+++ gcc/cp/pt.c	2017-02-15 18:21:45.581055915 +0100
@@ -10113,6 +10113,8 @@  apply_late_template_attributes (tree *de
 
       cplus_decl_attributes (decl_p, late_attrs, attr_flags);
     }
+  else
+    *p = attributes;
 }
 
 /* Perform (or defer) access check for typedefs that were referenced
--- gcc/testsuite/g++.dg/cpp1z/nodiscard4.C.jj	2017-02-15 18:11:33.281135469 +0100
+++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C	2017-02-15 18:11:33.281135469 +0100
@@ -0,0 +1,14 @@ 
+// PR c++/79502
+// { dg-do compile { target c++11 } }
+
+template<typename>
+struct [[nodiscard]] missiles {};
+
+missiles<void> make() { return {}; }
+missiles<void> (*fnptr)() = make;
+
+int main()
+{
+  make();	// { dg-warning "ignoring returned value of type" }
+  fnptr();	// { dg-warning "ignoring returned value of type" }
+}