public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jason Merrill <jason@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r9-10169] c++: C++17 constexpr static data member linkage [PR99901]
Date: Fri, 13 May 2022 17:41:27 +0000 (GMT)	[thread overview]
Message-ID: <20220513174127.DFA4F395B43C@sourceware.org> (raw)

https://gcc.gnu.org/g:623842bead8452c03f2b1c6817f2a86a1d2d4d12

commit r9-10169-g623842bead8452c03f2b1c6817f2a86a1d2d4d12
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Apr 6 01:21:05 2021 -0400

    c++: C++17 constexpr static data member linkage [PR99901]
    
    C++17 makes constexpr static data members implicitly inline variables.  In
    C++14, a subsequent out-of-class declaration is the definition.  We want to
    continue emitting a symbol for such a declaration in C++17 mode, for ABI
    compatibility with C++14 code that wants to refer to it.
    
    Normally I'd distinguish in- and out-of-class declarations by looking at
    DECL_IN_AGGR_P, but we never set DECL_IN_AGGR_P on inline variables.  I
    think that's wrong, but don't want to mess with it so close to release.
    Conveniently, we already have a test for in-class declaration earlier in the
    function.
    
    gcc/cp/ChangeLog:
    
            PR c++/99901
            * decl.c (cp_finish_decl): mark_needed an implicitly inline
            static data member with an out-of-class redeclaration.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/99901
            * g++.dg/cpp1z/inline-var9.C: New test.

Diff:
---
 gcc/cp/decl.c                            | 18 ++++++++++----
 gcc/testsuite/g++.dg/cpp1z/inline-var9.C | 40 ++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 565f5711fd5..7fb669fd48f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7010,10 +7010,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (asmspec_tree && asmspec_tree != error_mark_node)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
-  if (current_class_type
-      && CP_DECL_CONTEXT (decl) == current_class_type
-      && TYPE_BEING_DEFINED (current_class_type)
-      && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
+  bool in_class_decl
+    = (current_class_type
+       && CP_DECL_CONTEXT (decl) == current_class_type
+       && TYPE_BEING_DEFINED (current_class_type)
+       && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type));
+
+  if (in_class_decl
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
@@ -7345,6 +7348,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 	{
 	  layout_var_decl (decl);
 	  maybe_commonize_var (decl);
+	  /* A class-scope constexpr variable with an out-of-class declaration.
+	     C++17 makes them implicitly inline, but still force it out.  */
+	  if (DECL_INLINE_VAR_P (decl)
+	      && !DECL_VAR_DECLARED_INLINE_P (decl)
+	      && !DECL_TEMPLATE_INSTANTIATION (decl)
+	      && !in_class_decl)
+	    mark_needed (decl);
 	}
 
       /* This needs to happen after the linkage is set. */
diff --git a/gcc/testsuite/g++.dg/cpp1z/inline-var9.C b/gcc/testsuite/g++.dg/cpp1z/inline-var9.C
new file mode 100644
index 00000000000..43c9748877b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/inline-var9.C
@@ -0,0 +1,40 @@
+// PR c++/99901
+// { dg-do compile { target c++11 } }
+// { dg-final { scan-assembler-not "_ZN1A1aE" } }
+// { dg-final { scan-assembler-not "_ZN2A21aE" } }
+// { dg-final { scan-assembler-not "_ZN1CIiE1cE" } }
+// { dg-final { scan-assembler "_ZN1B1bE" } }
+// { dg-final { scan-assembler "_ZN2B21bE" } }
+// { dg-final { scan-assembler "_ZN2B31bE" } }
+
+struct A {
+  static const int a = 5;
+};
+
+struct A2 {
+  static constexpr int a = 5;
+};
+
+struct B {
+  static const int b;
+};
+constexpr int B::b = 5;
+
+struct B2 {
+  static const int b = 5;
+};
+constexpr int B2::b;
+
+struct B3 {
+  static constexpr int b = 5;
+};
+const int B3::b;
+
+template <class T>
+struct C {
+  static constexpr int c = 5;
+};
+template <class T>
+constexpr int C<T>::c;
+
+int i = C<int>::c;


                 reply	other threads:[~2022-05-13 17:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220513174127.DFA4F395B43C@sourceware.org \
    --to=jason@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).