aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2021-01-12 16:16:44 -0500
committerMarek Polacek <polacek@redhat.com>2021-01-21 19:22:01 -0500
commitbca467e56fe111fa6d876656c60d5704065e83fe (patch)
treeb3b2b30911d0fbfd08bf01044ab9a3319845aa98 /gcc/cp
parent070a1fb5f5254a08cd87783a1b51c3a3ac7ae18e (diff)
downloadgcc-bca467e56fe111fa6d876656c60d5704065e83fe.zip
gcc-bca467e56fe111fa6d876656c60d5704065e83fe.tar.gz
gcc-bca467e56fe111fa6d876656c60d5704065e83fe.tar.bz2
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.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/pt.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 373f827..63a0a11 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11895,6 +11895,9 @@ instantiate_class_template_1 (tree type)
relative to the scope of the class. */
pop_to_parent_deferring_access_checks ();
+ /* A vector to hold members marked with attribute used. */
+ auto_vec<tree> used;
+
/* Now members are processed in the order of declaration. */
for (member = CLASSTYPE_DECL_LIST (pattern);
member; member = TREE_CHAIN (member))
@@ -11968,7 +11971,7 @@ instantiate_class_template_1 (tree type)
finish_member_declaration (r);
/* Instantiate members marked with attribute used. */
if (r != error_mark_node && DECL_PRESERVE_P (r))
- mark_used (r);
+ used.safe_push (r);
if (TREE_CODE (r) == FUNCTION_DECL
&& DECL_OMP_DECLARE_REDUCTION_P (r))
cp_check_omp_declare_reduction (r);
@@ -12034,7 +12037,7 @@ instantiate_class_template_1 (tree type)
/*flags=*/0);
/* Instantiate members marked with attribute used. */
if (r != error_mark_node && DECL_PRESERVE_P (r))
- mark_used (r);
+ used.safe_push (r);
}
else if (TREE_CODE (r) == FIELD_DECL)
{
@@ -12225,6 +12228,11 @@ instantiate_class_template_1 (tree type)
if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type))
vec_safe_push (keyed_classes, type);
+ /* Now that we've gone through all the members, instantiate those
+ marked with attribute used. */
+ for (tree x : used)
+ mark_used (x);
+
return type;
}