diff mbox series

C++ PATCH for c++/87921, wrong error with inline static data member

Message ID CADzB+2nBnsUAd_=70nmiA=0oUgqn12CdtEBiUY1u6OXd8y+dBQ@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/87921, wrong error with inline static data member | expand

Commit Message

Jason Merrill Feb. 21, 2019, 2:21 a.m. UTC
c_parse_final_cleanups checks DECL_IN_AGGR_P to avoid trying to emit a
static data member that has not been defined.  The inline variable
patch changed that to exempt inline variables.  But in this case we
haven't instantiated the variable yet, so we really don't have a
definition.

I've taken different approaches to fixing this in trunk and GCC 8: for
GCC 8 I just fix this place.  For the trunk I replace various places
needing to check DECL_IN_AGGR_P && !DECL_INLINE_VAR_P with setting
DECL_IN_AGGR_P appropriately for inline variables.

Tested x86_64-pc-linux-gnu, applying to trunk; I'll apply the GCC 8
patch after the branch thaws.
diff mbox series

Patch

commit 74c41e559636a78b8415467ce2ca7ea0eb641956
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Feb 19 16:47:22 2019 -1000

            PR c++/87921 - wrong error with inline static data member.
    
    An instantiation of an inline variable isn't defined until it's
    instantiated, so don't treat it as defined just because it's inline.
    
            * decl2.c (c_parse_final_cleanups): Don't force out uninstantiated
            inline static data members.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 6a67c4e5b33..1043af49b91 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4905,7 +4905,10 @@  c_parse_final_cleanups (void)
 	{
 	  if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl)
 	      /* Don't write it out if we haven't seen a definition.  */
-	      || (DECL_IN_AGGR_P (decl) && !DECL_INLINE_VAR_P (decl)))
+	      || (DECL_IN_AGGR_P (decl) && !DECL_INLINE_VAR_P (decl))
+	      /* Or haven't instantiated it.  */
+	      || (DECL_TEMPLATE_INSTANTIATION (decl)
+		  && !DECL_TEMPLATE_INSTANTIATED (decl)))
 	    continue;
 	  import_export_decl (decl);
 	  /* If this static data member is needed, provide it to the
diff --git a/gcc/testsuite/g++.dg/cpp1z/inline-var5.C b/gcc/testsuite/g++.dg/cpp1z/inline-var5.C
new file mode 100644
index 00000000000..27730106f27
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/inline-var5.C
@@ -0,0 +1,16 @@ 
+// PR c++/87921
+// { dg-do compile { target c++17 } }
+
+template <class H>
+struct X
+{
+  static inline long x[] = { 1L };
+  long foo () { return x[0]; }
+};
+
+void
+bar ()
+{
+  class L {};
+  X<L> v {};
+}