![]() [basic.link] p14 lists a number of circumstances where a declaration naming a TU-local entity is not an exposure, notably the bodies of non-inline templates and friend declarations in classes. This patch ensures that these references do not error when exporting the module. We do need to still error on instantiation from a different module, however, in case this refers to a TU-local entity. As such this patch adds a new tree TU_LOCAL_ENTITY which is used purely as a placeholder to poison any attempted template instantiations that refer to it. This is also streamed for friend decls so that merging (based on the index of an entity into the friend decl list) doesn't break and to prevent complicating the logic; I imagine this shouldn't ever come up though. We also add a new warning, '-Wtemplate-names-tu-local', to handle the case where someone accidentally refers to a TU-local value from within a non-inline function template. This will compile without errors as-is, but any attempt to instantiate the decl will fail; this warning can be used to ensure that this doesn't happen. The warning is silenced for any declarations with explicit instantiations, since uses of those instantiations would not be exposures. The main piece that this patch doesn't yet attempt to solve is ADL: as specified, if ADL adds an overload set that includes a translation-unit local entity when instantiating a template, that overload set is now poisoned and counts as an exposure. Unfortunately, we don't currently differentiate between decls that are hidden due to not being exported, or decls that are hidden due to being hidden friends, so this patch instead just keeps the current (wrong) behaviour of non-exported entities not being visible to ADL at all. Additionally, this patch doesn't attempt to ignore non-ODR uses of constants in constexpr functions or templates. The obvious approach of folding them early in 'mark_use' doesn't seem to work (for a variety of reasons), so this leaves this to a later patch to implement, as it's at least no worse than the current behaviour and easy enough to workaround. For completeness this patch adds a new xtreme-header testcase to ensure that we have no regressions with regards to exposures of TU-local declarations in the standard library header files. A more restrictive test would be to do 'export extern "C++"' here, but unfortunately the system headers on some targets declare TU-local entities, so we'll make do with checking that at least the C++ standard library headers don't refer to such entities. gcc/c-family/ChangeLog: * c.opt: New warning '-Wtemplate-names-tu-local'. gcc/cp/ChangeLog: * cp-objcp-common.cc (cp_tree_size): Add TU_LOCAL_ENTITY. * cp-tree.def (TU_LOCAL_ENTITY): New tree code. * cp-tree.h (DECL_TEMPLATE_INSTANTIATIONS): Update comment. (struct tree_tu_local_entity): New type. (TU_LOCAL_ENTITY_NAME): New accessor. (TU_LOCAL_ENTITY_LOCATION): New accessor. (enum cp_tree_node_structure_enum): Add TS_CP_TU_LOCAL_ENTITY. (union GTY): Add tu_local_entity field. * module.cc (enum tree_tag): New flag DB_REFS_TU_LOCAL_BIT. (depset::has_defn): Override for TU-local entities. (depset::refs_tu_local): New accessor. (depset:#️⃣:ignore_tu_local): New field. (depset:#️⃣:hash): Initialize it. (trees_out::tree_tag::tt_tu_local): New flag. (trees_out::writing_local_entities): New field. (trees_out::is_initial_scan): New function. (trees_out::tu_local_count): New counter. (trees_out::trees_out): Initialize writing_local_entities. (dumper::impl::nested_name): Handle TU_LOCAL_ENTITY. (trees_out::instrument): Report TU-local entity counts. (trees_out::decl_value): Early exit for TU-local entities. (trees_in::decl_value): Handle typedefs of TU-local entities. (trees_out::decl_node): Adjust assertion to cope with early exit of TU-local deps. Always write TU-local entities by value. (trees_out::type_node): Handle TU-local types. (trees_out::has_tu_local_dep): New function. (trees_out::find_tu_local_decl): New function. (trees_out::tree_node): Intercept TU-local entities and write placeholder values for them instead of normal streaming. (trees_in::tree_node): Handle TU-local entities and TU-local template results. (trees_out::write_function_def): Ignore exposures in non-inline function bodies. (trees_out::write_var_def): Ignore exposures in initializers. (trees_out::write_class_def): Ignore exposures in friend decls. (trees_in::read_class_def): Skip TU-local friends. (trees_out::write_definition): Record whether we're writing a decl which refers to TU-local entities. (depset:#️⃣:add_dependency): Only mark as exposure if we're not ignoring TU-local entities. (depset:#️⃣:find_dependencies): Use depset's own is_key_order function rather than delegating via walker. Pass whether the decl has ignored TU-local entities in its definition. (template_has_explicit_inst): New function. (depset:#️⃣:finalize_dependencies): Implement new warning Wtemplate-names-tu-local. (module_state::intercluster_seed): Don't seed TU-local deps. (module_state::write_cluster): Pass whether the decl has ignored TU-local entities in its definition. * pt.cc (register_specialization): Always register in a module. (complain_about_tu_local_entity): New function. (expr_contains_tu_local_entity): New function. (function_contains_tu_local_entity): New function. (instantiate_class_template): Skip TU-local friends. (tsubst_decl): Handle typedefs of TU-local entities. (tsubst): Complain about TU-local entities. (dependent_operand_p): Early exit for TU-local entities so we don't attempt to constant-evaluate them. (tsubst_expr): Detect and complain about TU-local entities. gcc/ChangeLog: * doc/invoke.texi: Document -Wtemplate-names-tu-local. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-5_a.C: New test. * g++.dg/modules/internal-5_b.C: New test. * g++.dg/modules/internal-6.C: New test. * g++.dg/modules/internal-7_a.C: New test. * g++.dg/modules/internal-7_b.C: New test. * g++.dg/modules/internal-8_a.C: New test. * g++.dg/modules/xtreme-header-8.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> |
||
---|---|---|
.forgejo | ||
.github | ||
c++tools | ||
config | ||
contrib | ||
fixincludes | ||
gcc | ||
gnattools | ||
gotools | ||
include | ||
INSTALL | ||
libada | ||
libatomic | ||
libbacktrace | ||
libcc1 | ||
libcody | ||
libcpp | ||
libdecnumber | ||
libffi | ||
libgcc | ||
libgfortran | ||
libgm2 | ||
libgo | ||
libgomp | ||
libgrust | ||
libiberty | ||
libitm | ||
libobjc | ||
libphobos | ||
libquadmath | ||
libsanitizer | ||
libssp | ||
libstdc++-v3 | ||
libvtv | ||
lto-plugin | ||
maintainer-scripts | ||
zlib | ||
.b4-config | ||
.dir-locals.el | ||
.gitattributes | ||
.gitignore | ||
ABOUT-NLS | ||
ar-lib | ||
ChangeLog | ||
ChangeLog.jit | ||
ChangeLog.tree-ssa | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING.LIB | ||
COPYING.RUNTIME | ||
COPYING3 | ||
COPYING3.LIB | ||
depcomp | ||
install-sh | ||
libtool-ldflags | ||
libtool.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
lt~obsolete.m4 | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
missing | ||
mkdep | ||
mkinstalldirs | ||
move-if-change | ||
multilib.am | ||
README | ||
SECURITY.txt | ||
symlink-tree | ||
test-driver | ||
ylwrap |
This directory contains the GNU Compiler Collection (GCC). The GNU Compiler Collection is free software. See the files whose names start with COPYING for copying permission. The manuals, and some of the runtime libraries, are under different terms; see the individual source files for details. The directory INSTALL contains copies of the installation information as HTML and plain text. The source of this information is gcc/doc/install.texi. The installation information includes details of what is included in the GCC sources and what files GCC installs. See the file gcc/doc/gcc.texi (together with other files that it includes) for usage and porting information. An online readable version of the manual is in the files gcc/doc/gcc.info*. See http://gcc.gnu.org/bugs/ for how to report bugs usefully. Copyright years on GCC source files may be listed using range notation, e.g., 1987-2012, indicating that every year in the range, inclusive, is a copyrightable year that could otherwise be listed individually.