From 5f3c6027257118469a722816e228394b5978ddb0 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 30 Mar 2021 09:45:59 -0700 Subject: [PATCH] c++: duplicate const static members [PR 99283] 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. --- gcc/cp/module.cc | 22 ++++++++++++++-------- gcc/testsuite/g++.dg/modules/pr99283-5.h | 9 +++++++++ gcc/testsuite/g++.dg/modules/pr99283-5_a.H | 14 ++++++++++++++ gcc/testsuite/g++.dg/modules/pr99283-5_b.H | 12 ++++++++++++ gcc/testsuite/g++.dg/modules/pr99283-5_c.C | 5 +++++ 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/pr99283-5.h create mode 100644 gcc/testsuite/g++.dg/modules/pr99283-5_a.H create mode 100644 gcc/testsuite/g++.dg/modules/pr99283-5_b.H create mode 100644 gcc/testsuite/g++.dg/modules/pr99283-5_c.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 8a1cfbdfdcb..fab6b573d24 100644 --- a/gcc/cp/module.cc +++ b/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 a/gcc/testsuite/g++.dg/modules/pr99283-5.h b/gcc/testsuite/g++.dg/modules/pr99283-5.h new file mode 100644 index 00000000000..3c3421f2d1c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-5.h @@ -0,0 +1,9 @@ +template +struct __traits +{ + static const int __digits = 8; + static const _Value __min = 0; +}; + +template +const _Value __traits<_Value>::__min; diff --git a/gcc/testsuite/g++.dg/modules/pr99283-5_a.H b/gcc/testsuite/g++.dg/modules/pr99283-5_a.H new file mode 100644 index 00000000000..6406dfe8102 --- /dev/null +++ b/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 +const int __traits<_Value>::__digits; + +template +void Foo () +{ + __traits::__digits; +} diff --git a/gcc/testsuite/g++.dg/modules/pr99283-5_b.H b/gcc/testsuite/g++.dg/modules/pr99283-5_b.H new file mode 100644 index 00000000000..3f4237e2e4f --- /dev/null +++ b/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 +void Bar () +{ + __traits::__min; +} + +import "pr99283-5_a.H"; diff --git a/gcc/testsuite/g++.dg/modules/pr99283-5_c.C b/gcc/testsuite/g++.dg/modules/pr99283-5_c.C new file mode 100644 index 00000000000..cc7e795c829 --- /dev/null +++ b/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::__min);