diff options
author | Jason Merrill <jason@redhat.com> | 2023-06-27 05:15:01 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-06-28 00:42:12 -0400 |
commit | abdf0b6cdff5783b97f35ad61ae31433f0569dfd (patch) | |
tree | 883f684665687209e8f4b227992d40086420227c /gcc/cp/optimize.cc | |
parent | 83f69969c0f3eb93302f6ef7714884db9079e803 (diff) | |
download | gcc-abdf0b6cdff5783b97f35ad61ae31433f0569dfd.zip gcc-abdf0b6cdff5783b97f35ad61ae31433f0569dfd.tar.gz gcc-abdf0b6cdff5783b97f35ad61ae31433f0569dfd.tar.bz2 |
c++: inherited constructor attributes
Inherited constructors are like constructor clones; they don't exist from
the language perspective, so they should copy the attributes in the same
way. But it doesn't make sense to copy alias or ifunc attributes in either
case. Unlike handle_copy_attribute, we do want to copy inlining attributes.
The discussion of PR110334 pointed out that we weren't copying the
always_inline attribute, leading to poor inlining choices.
PR c++/110334
gcc/cp/ChangeLog:
* cp-tree.h (clone_attrs): Declare.
* method.cc (implicitly_declare_fn): Use it for inherited
constructor.
* optimize.cc (clone_attrs): New.
(maybe_clone_body): Use it.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/nodiscard-inh1.C: New test.
Diffstat (limited to 'gcc/cp/optimize.cc')
-rw-r--r-- | gcc/cp/optimize.cc | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc index f73d86b..9e8926e 100644 --- a/gcc/cp/optimize.cc +++ b/gcc/cp/optimize.cc @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "tree-inline.h" #include "tree-iterator.h" +#include "attribs.h" /* Prototypes. */ @@ -446,6 +447,29 @@ maybe_thunk_body (tree fn, bool force) return 1; } +/* Copy most attributes from ATTRS, omitting attributes that can really only + apply to a single decl. */ + +tree +clone_attrs (tree attrs) +{ + tree new_attrs = NULL_TREE; + tree *p = &new_attrs; + + for (tree a = attrs; a; a = TREE_CHAIN (a)) + { + tree aname = get_attribute_name (a); + if (is_attribute_namespace_p ("", a) + && (is_attribute_p ("alias", aname) + || is_attribute_p ("ifunc", aname))) + continue; + *p = copy_node (a); + p = &TREE_CHAIN (*p); + } + *p = NULL_TREE; + return new_attrs; +} + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -503,7 +527,7 @@ maybe_clone_body (tree fn) DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn); DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn); - DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn)); + DECL_ATTRIBUTES (clone) = clone_attrs (DECL_ATTRIBUTES (fn)); DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn); set_decl_section_name (clone, fn); |