From: Nathan Sidwell Date: Fri, 2 Apr 2021 13:28:29 +0000 (-0700) Subject: c++: header unit purview [PR 99283] X-Git-Tag: basepoints/gcc-12~297 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4e05eebd6aac6118cbd9e0a04c011b6ed682826;p=thirdparty%2Fgcc.git c++: header unit purview [PR 99283] This case occurs due to some equivocation about module_purview. Header-unit building is treated as a module-purview, but we should not treat entities imported from that as module purview. (header units were not a thing when I started). The testcase didn't understand we had a local textual definition, but it was (incorrectly) marked as module-purview, because we'd read in a declaration from a header unit too. gcc/cp/ * cp-tree.h (lang_decl_base): Correct module flag comment. * module.cc (trees_in::assert_definition): Break out not_tmpl var. (trees_out::lang_decl_bools): Do not write purview for header units. gcc/testsuite/ * g++.dg/modules/pr99283-6_d.H: New. * g++.dg/modules/pr99283-7-swap.h: New. * g++.dg/modules/pr99283-7-traits.h: New. * g++.dg/modules/pr99283-7_a.H: New. * g++.dg/modules/pr99283-7_b.H: New. * g++.dg/modules/pr99283-7_c.C: New. * g++.dg/modules/pr99283-7_d.H: New. --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9535910fd4ea..66bba7b4d43e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2756,8 +2756,8 @@ struct GTY(()) lang_decl_base { unsigned var_declared_inline_p : 1; /* var */ unsigned dependent_init_p : 1; /* var */ - /* The following apply to VAR, FUNCTION, TYPE, CONCEPT, TEMPLATE, - NAMESPACE decls. */ + /* The following apply to VAR, FUNCTION, TYPE, CONCEPT, & NAMESPACE + decls. */ unsigned module_purview_p : 1; /* in module purview (not GMF) */ unsigned module_import_p : 1; /* from an import */ unsigned module_entity_p : 1; /* is in the entitity ary & diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c87ddd16a80d..d5b7d28ded54 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -4477,6 +4477,7 @@ trees_in::assert_definition (tree decl ATTRIBUTE_UNUSED, { #if CHECKING_P tree *slot = note_defs->find_slot (decl, installing ? INSERT : NO_INSERT); + tree not_tmpl = STRIP_TEMPLATE (decl); if (installing) { /* We must be inserting for the first time. */ @@ -4492,13 +4493,13 @@ trees_in::assert_definition (tree decl ATTRIBUTE_UNUSED, gcc_assert (!is_duplicate (decl) ? !slot : (slot - || !DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) - || !DECL_MODULE_PURVIEW_P (STRIP_TEMPLATE (decl)) - || (!DECL_MODULE_IMPORT_P (STRIP_TEMPLATE (decl)) + || !DECL_LANG_SPECIFIC (not_tmpl) + || !DECL_MODULE_PURVIEW_P (not_tmpl) + || (!DECL_MODULE_IMPORT_P (not_tmpl) && header_module_p ()))); - if (TREE_CODE (decl) == TEMPLATE_DECL) - gcc_assert (!note_defs->find_slot (DECL_TEMPLATE_RESULT (decl), NO_INSERT)); + if (not_tmpl != decl) + gcc_assert (!note_defs->find_slot (not_tmpl, NO_INSERT)); #endif } @@ -5519,7 +5520,9 @@ trees_out::lang_decl_bools (tree t) WB (lang->u.base.concept_p); WB (lang->u.base.var_declared_inline_p); WB (lang->u.base.dependent_init_p); - WB (lang->u.base.module_purview_p); + /* When building a header unit, everthing is marked as purview, but + that's the GM purview, so not what the importer will mean */ + WB (lang->u.base.module_purview_p && !header_module_p ()); if (VAR_OR_FUNCTION_DECL_P (t)) WB (lang->u.base.module_attached_p); switch (lang->u.base.selector) @@ -11304,7 +11307,7 @@ trees_in::register_duplicate (tree decl, tree existing) /* We've read a definition of MAYBE_EXISTING. If not a duplicate, return MAYBE_EXISTING (into which the definition should be installed). Otherwise return NULL if already known bad, or the - duplicate we read (for ODR checking, or extracting addtional merge + duplicate we read (for ODR checking, or extracting additional merge information). */ tree diff --git a/gcc/testsuite/g++.dg/modules/pr99283-6_d.H b/gcc/testsuite/g++.dg/modules/pr99283-6_d.H new file mode 100644 index 000000000000..e8114711f38c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-6_d.H @@ -0,0 +1,10 @@ +// { dg-additional-options {-std=c++2a -fmodule-header} } + +import "pr99283-6_b.H"; + +template +struct __allocated_ptr +{ + using value_type = allocator_traits<_Alloc>; +}; + diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7-swap.h b/gcc/testsuite/g++.dg/modules/pr99283-7-swap.h new file mode 100644 index 000000000000..d725fea9ee54 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7-swap.h @@ -0,0 +1,17 @@ +template +constexpr typename remove_reference<_Tp>::type&& + move(_Tp&& __t) noexcept; + +template +constexpr inline +typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, + is_move_constructible<_Tp>, + is_move_assignable<_Tp>>::value>::type + swap(_Tp& __a, _Tp& __b) + noexcept(__and_, + is_nothrow_move_assignable<_Tp>>::value) +{ + _Tp __tmp = move(__a); + __a = move(__b); + __b = move(__tmp); +} diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7-traits.h b/gcc/testsuite/g++.dg/modules/pr99283-7-traits.h new file mode 100644 index 000000000000..8f6bce04bee7 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7-traits.h @@ -0,0 +1,41 @@ +template +struct __and_; + +template +struct __not_; + +template +struct is_move_constructible; + +template +struct is_nothrow_move_constructible; + +template +struct is_move_assignable; + +template +struct is_nothrow_move_assignable; + +template +struct remove_reference; + +template +struct enable_if; + +template +using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + +template +using _Require = __enable_if_t<__and_<_Cond...>::value>; + +template +struct __is_tuple_like; + +template +constexpr inline + _Require<__not_<__is_tuple_like<_Tp>>, + is_move_constructible<_Tp>, + is_move_assignable<_Tp>> +swap(_Tp&, _Tp&) + noexcept(__and_, + is_nothrow_move_assignable<_Tp>>::value); diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7_a.H b/gcc/testsuite/g++.dg/modules/pr99283-7_a.H new file mode 100644 index 000000000000..b52d44d5c26f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7_a.H @@ -0,0 +1,97 @@ +// PR 99283, +// { dg-additional-options "-std=c++2a -fmodule-header" } +// { dg-module-cmi {} } + +#include "pr99283-7-traits.h" + +template +struct char_traits; + +template> +class basic_string; + +typedef basic_string string; + +template +struct integral_constant +{ + static constexpr _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } +}; + +template +constexpr _Tp integral_constant<_Tp, __v>::value; + +typedef integral_constant true_type; + +typedef integral_constant false_type; + +template +using __bool_constant = integral_constant; + +template +_Up __declval(int); + +template +_Tp __declval(long); + +template +auto declval() noexcept -> decltype(__declval<_Tp>(0)); + +struct __do_is_nothrow_swappable_impl +{ + template + static __bool_constant< + noexcept(swap(declval<_Tp&>(), declval<_Tp&>())) + > __test(int); +}; + + + +template +struct __is_nothrow_swappable_impl + : public __do_is_nothrow_swappable_impl +{ + typedef decltype(__test<_Tp>(0)) type; +}; + +template +struct __is_nothrow_swappable + : public __is_nothrow_swappable_impl<_Tp>::type +{ }; + +#include "pr99283-7-swap.h" + +class partial_ordering +{ +public: + friend constexpr bool + operator==(partial_ordering, partial_ordering) noexcept = default; +}; + +class strong_ordering +{ +public: + constexpr operator partial_ordering() const noexcept; +}; + +template +struct pair +{ + constexpr void + swap(pair& __p) + noexcept(__is_nothrow_swappable<_T1>::value); +}; + +template +inline constexpr bool + operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y); + +template +struct char_traits +{ + using comparison_category = strong_ordering; +}; diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7_b.H b/gcc/testsuite/g++.dg/modules/pr99283-7_b.H new file mode 100644 index 000000000000..50c780e096e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-std=c++2a -fmodule-header" } +// { dg-module-cmi {} } + +#include "pr99283-7-traits.h" diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7_c.C b/gcc/testsuite/g++.dg/modules/pr99283-7_c.C new file mode 100644 index 000000000000..195bc684e409 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts" } +import "pr99283-7_b.H"; + +#include "pr99283-7-swap.h" + +import "pr99283-7_a.H"; + +void Xlocale(const string& __s); diff --git a/gcc/testsuite/g++.dg/modules/pr99283-7_d.H b/gcc/testsuite/g++.dg/modules/pr99283-7_d.H new file mode 100644 index 000000000000..ef4934beac0d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99283-7_d.H @@ -0,0 +1,8 @@ +// { dg-additional-options "-std=c++2a -fmodule-header" } +import "pr99283-7_b.H"; + +#include "pr99283-7-swap.h" + +import "pr99283-7_a.H"; + +void Xlocale(const string& __s);