diff mbox series

c++: duplicate const static members [PR 99283]

Message ID ef287fe7-8801-6743-ae34-95f50a51dabf@acm.org
State New
Headers show
Series c++: duplicate const static members [PR 99283] | expand

Commit Message

Nathan Sidwell March 30, 2021, 4:51 p.m. UTC
This is	the bug	that keeps on giving.  Reducing	it has been successful 
at hitting other defects. In this case, some more specialization hash 
table fun, plus an issue with reading in a definition of a duplicated 
declaration.  At least I discovered a null context check is no longer 
needed.

         PR c++/99283
         gcc/cp/
         * module.cc (dumper::operator):	Make less brittle.
         (trees_out::core_bools): VAR_DECLs always have a context.
         (trees_out::key_mergeable): Use	same_type_p for	asserting.
         (trees_in::read_var_def): Propagate
         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
         gcc/testsuite/
         * g++.dg/modules/pr99283-5.h: New.
         * g++.dg/modules/pr99283-5_a.H: New.
         * g++.dg/modules/pr99283-5_b.H: New.
         * g++.dg/modules/pr99283-5_c.C: New.
diff mbox series

Patch

diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc
index 8a1cfbdfdcb..fab6b573d24 100644
--- c/gcc/cp/module.cc
+++ w/gcc/cp/module.cc
@@ -4325,8 +4325,8 @@  dumper::operator () (const char *format, ...)
 	case 'N': /* Name.  */
 	  {
 	    tree t = va_arg (args, tree);
-	    if (t && TREE_CODE (t) == OVERLOAD)
-	      t = OVL_FIRST (t);
+	    while (t && TREE_CODE (t) == OVERLOAD)
+	      t = OVL_FUNCTION (t);
 	    fputc ('\'', dumps->stream);
 	    dumps->nested_name (t);
 	    fputc ('\'', dumps->stream);
@@ -5206,8 +5206,7 @@  trees_out::core_bools (tree t)
       else if (code == VAR_DECL)
 	{
 	  /* This is DECL_INITIALIZED_P.  */
-	  if (DECL_CONTEXT (t)
-	      && TREE_CODE (DECL_CONTEXT (t)) != FUNCTION_DECL)
+	  if (TREE_CODE (DECL_CONTEXT (t)) != FUNCTION_DECL)
 	    /* We'll set this when reading the definition.  */
 	    flag_1 = false;
 	}
@@ -10331,8 +10330,8 @@  trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
 	      if (mk & MK_tmpl_alias_mask)
 		/* It should be in both tables.  */
 		gcc_checking_assert
-		  (match_mergeable_specialization (false, entry)
-		   == TREE_TYPE (existing));
+		  (same_type_p (match_mergeable_specialization (false, entry),
+				TREE_TYPE (existing)));
 	      if (mk & MK_tmpl_tmpl_mask)
 		existing = DECL_TI_TEMPLATE (existing);
 	    }
@@ -10345,7 +10344,10 @@  trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
 	    }
 
 	  /* The walkabout should have found ourselves.  */
-	  gcc_checking_assert (existing == decl);
+	  gcc_checking_assert (TREE_CODE (decl) == TYPE_DECL
+			       ? same_type_p (TREE_TYPE (decl),
+					      TREE_TYPE (existing))
+			       : existing == decl);
 	}
     }
   else if (mk != MK_unique)
@@ -11513,7 +11515,11 @@  trees_in::read_var_def (tree decl, tree maybe_template)
       if (DECL_EXTERNAL (decl))
 	DECL_NOT_REALLY_EXTERN (decl) = true;
       if (VAR_P (decl))
-	DECL_INITIALIZED_P (decl) = true;
+	{
+	  DECL_INITIALIZED_P (decl) = true;
+	  if (maybe_dup && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (maybe_dup))
+	    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
+	}
       DECL_INITIAL (decl) = init;
       if (!dyn_init)
 	;
diff --git c/gcc/testsuite/g++.dg/modules/pr99283-5.h w/gcc/testsuite/g++.dg/modules/pr99283-5.h
new file mode 100644
index 00000000000..3c3421f2d1c
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99283-5.h
@@ -0,0 +1,9 @@ 
+template<typename _Value>
+struct __traits
+{
+  static const int __digits = 8;
+  static const _Value __min = 0;
+};
+
+template<typename _Value>
+const _Value __traits<_Value>::__min;
diff --git c/gcc/testsuite/g++.dg/modules/pr99283-5_a.H w/gcc/testsuite/g++.dg/modules/pr99283-5_a.H
new file mode 100644
index 00000000000..6406dfe8102
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99283-5_a.H
@@ -0,0 +1,14 @@ 
+// PR 99283 part 5
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+#include "pr99283-5.h"
+
+template<typename _Value>
+const int __traits<_Value>::__digits;
+
+template<typename _Tp>
+void Foo ()
+{
+  __traits<unsigned>::__digits;
+}
diff --git c/gcc/testsuite/g++.dg/modules/pr99283-5_b.H w/gcc/testsuite/g++.dg/modules/pr99283-5_b.H
new file mode 100644
index 00000000000..3f4237e2e4f
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99283-5_b.H
@@ -0,0 +1,12 @@ 
+// { dg-additional-options {-fmodule-header -fno-module-lazy} }
+// { dg-module-cmi {} }
+
+#include "pr99283-5.h"
+
+template<typename _Tp>
+void Bar ()
+{
+  __traits<unsigned>::__min;
+}
+
+import  "pr99283-5_a.H";
diff --git c/gcc/testsuite/g++.dg/modules/pr99283-5_c.C w/gcc/testsuite/g++.dg/modules/pr99283-5_c.C
new file mode 100644
index 00000000000..cc7e795c829
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99283-5_c.C
@@ -0,0 +1,5 @@ 
+// { dg-additional-options {-fmodules-ts -fno-module-lazy} }
+
+import  "pr99283-5_b.H";
+
+static_assert(!__traits<unsigned>::__min);