public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2149] c++: inherited constructor attributes
@ 2023-06-28  4:42 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2023-06-28  4:42 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:abdf0b6cdff5783b97f35ad61ae31433f0569dfd

commit r14-2149-gabdf0b6cdff5783b97f35ad61ae31433f0569dfd
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jun 27 05:15:01 2023 -0400

    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.

Diff:
---
 gcc/cp/cp-tree.h                            |  1 +
 gcc/cp/method.cc                            |  2 ++
 gcc/cp/optimize.cc                          | 26 +++++++++++++++++++++++++-
 gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C | 15 +++++++++++++++
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 83982233111..0d7a6c153dc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7282,6 +7282,7 @@ extern void module_preprocess_options (cpp_reader *);
 extern bool handle_module_option (unsigned opt, const char *arg, int value);
 
 /* In optimize.cc */
+extern tree clone_attrs				(tree);
 extern bool maybe_clone_body			(tree);
 
 /* In parser.cc */
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 91cf943f110..8ed967ddb21 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -3294,6 +3294,8 @@ implicitly_declare_fn (special_function_kind kind, tree type,
       /* Copy constexpr from the inherited constructor even if the
 	 inheriting constructor doesn't satisfy the requirements.  */
       constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
+      /* Also copy any attributes.  */
+      DECL_ATTRIBUTES (fn) = clone_attrs (DECL_ATTRIBUTES (inherited_ctor));
     }
 
   /* Add the "this" parameter.  */
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index f73d86b6c6b..9e8926e4cc6 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);
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C
new file mode 100644
index 00000000000..bc2555930f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard-inh1.C
@@ -0,0 +1,15 @@
+// [[nodiscard]] should apply to inherited constructors.
+// { dg-do compile { target c++11 } }
+
+struct A {
+  [[nodiscard]] A(int);
+};
+
+struct B: A {
+  using A::A;
+};
+
+int main()
+{
+  B(42);				// { dg-warning nodiscard }
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-28  4:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-28  4:42 [gcc r14-2149] c++: inherited constructor attributes 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).