c++: ICE with delayed noexcept and attribute used [PR97966]
authorMarek Polacek <polacek@redhat.com>
Tue, 12 Jan 2021 21:16:44 +0000 (16:16 -0500)
committerMarek Polacek <polacek@redhat.com>
Fri, 22 Jan 2021 00:22:01 +0000 (19:22 -0500)
commitbca467e56fe111fa6d876656c60d5704065e83fe
treeb3b2b30911d0fbfd08bf01044ab9a3319845aa98
parent070a1fb5f5254a08cd87783a1b51c3a3ac7ae18e
c++: ICE with delayed noexcept and attribute used [PR97966]

Another ICE with delayed noexcept parsing, but a bit gnarlier.

A function definition marked with __attribute__((used)) ought to be
emitted even when it is not referenced in the TU.  For a member function
template marked with __attribute__((used)) this means that it will
be instantiated: in instantiate_class_template_1 we have

11971               /* Instantiate members marked with attribute used.  */
11972               if (r != error_mark_node && DECL_PRESERVE_P (r))
11973                 mark_used (r);

It is not so surprising that this doesn't work well with delayed
noexcept parsing: when we're processing the function template we delay
the parsing, so the member "foo" is found, but then when we're
instantiating it, "foo" hasn't yet been seen, which creates a
discrepancy and a crash ensues.  "foo" hasn't yet been seen because
instantiate_class_template_1 just loops over the class members and
instantiates right away.

To make it work, this patch uses a vector to keep track of members
marked with attribute used and uses it to instantiate such members
only after we're done with the class; in particular, after we have
called finish_member_declaration for each member.  And we ought to
be verifying that we did emit such members, so I've added a bunch
of dg-finals.

gcc/cp/ChangeLog:

PR c++/97966
* pt.c (instantiate_class_template_1): Instantiate members
marked with attribute used only after we're done instantiating
the class.

gcc/testsuite/ChangeLog:

PR c++/97966
* g++.dg/cpp0x/noexcept63.C: New test.
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/noexcept63.C [new file with mode: 0644]