Skip to content

Commit f5db79b

Browse files
committed
c++/modules: Complain on imported GMF TU-local entities in instantiation [PR121574]
An unfortunate side effect of the previous patch is that even with -pedantic-errors, unless the user specifies -Wtemplate-names-tu-local when building the module interface there will be no diagnostic at all from instantiating a template that exposes global TU-local entities, either when building the module or its importer. This patch solves this by recognising imported TU-local dependencies, even if they weren't streamed as TU_LOCAL_ENTITY nodes. The warnings here are deliberately conservative for when we can be sure this was actually an imported TU-local entity; in particular, we bail on any TU-local entity that originated from a header module, without attempting to determine if the entity came via a named module first. PR c++/121574 gcc/cp/ChangeLog: * cp-tree.h (instantiating_tu_local_entity): Declare. * module.cc (is_tu_local_entity): Extract from depset::hash. (is_tu_local_value): Likewise. (has_tu_local_tmpl_arg): Likewise. (depset::hash::is_tu_local_entity): Remove. (depset::hash::has_tu_local_tmpl_arg): Remove. (depset::hash::is_tu_local_value): Remove. (instantiating_tu_local_entity): New function. (depset::hash::add_binding_entity): No longer go through depset::hash to check is_tu_local_entity. * pt.cc (complain_about_tu_local_entity): Remove. (tsubst): Use instantiating_tu_local_entity. (tsubst_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-17_b.C: Check for diagnostics when instantiating imported TU-local entities. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
1 parent 99c2ed7 commit f5db79b

File tree

4 files changed

+84
-42
lines changed

4 files changed

+84
-42
lines changed

gcc/cp/cp-tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7745,6 +7745,8 @@ extern module_state *get_module (tree name, module_state *parent = NULL,
77457745
bool partition = false);
77467746
extern bool module_may_redeclare (tree olddecl, tree newdecl = NULL);
77477747

7748+
extern bool instantiating_tu_local_entity (tree decl);
7749+
77487750
extern bool module_global_init_needed ();
77497751
extern bool module_determine_import_inits ();
77507752
extern void module_add_import_initializers ();

gcc/cp/module.cc

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,11 +2663,6 @@ class depset {
26632663
depset *add_dependency (tree decl, entity_kind);
26642664
void add_namespace_context (depset *, tree ns);
26652665

2666-
private:
2667-
bool has_tu_local_tmpl_arg (tree decl, tree args, bool explain);
2668-
bool is_tu_local_entity (tree decl, bool explain = false);
2669-
bool is_tu_local_value (tree decl, tree expr, bool explain = false);
2670-
26712666
private:
26722667
static bool add_binding_entity (tree, WMB_Flags, void *);
26732668

@@ -13934,11 +13929,15 @@ depset::hash::find_binding (tree ctx, tree name)
1393413929
return slot ? *slot : NULL;
1393513930
}
1393613931

13932+
static bool is_tu_local_entity (tree decl, bool explain = false);
13933+
static bool is_tu_local_value (tree decl, tree expr, bool explain = false);
13934+
static bool has_tu_local_tmpl_arg (tree decl, tree args, bool explain);
13935+
1393713936
/* Returns true if DECL is a TU-local entity, as defined by [basic.link].
1393813937
If EXPLAIN is true, emit an informative note about why DECL is TU-local. */
1393913938

13940-
bool
13941-
depset::hash::is_tu_local_entity (tree decl, bool explain/*=false*/)
13939+
static bool
13940+
is_tu_local_entity (tree decl, bool explain/*=false*/)
1394213941
{
1394313942
gcc_checking_assert (DECL_P (decl));
1394413943
location_t loc = DECL_SOURCE_LOCATION (decl);
@@ -14104,8 +14103,8 @@ depset::hash::is_tu_local_entity (tree decl, bool explain/*=false*/)
1410414103
/* Helper for is_tu_local_entity. Returns true if one of the ARGS of
1410514104
DECL is TU-local. Emits an explanation if EXPLAIN is true. */
1410614105

14107-
bool
14108-
depset::hash::has_tu_local_tmpl_arg (tree decl, tree args, bool explain)
14106+
static bool
14107+
has_tu_local_tmpl_arg (tree decl, tree args, bool explain)
1410914108
{
1411014109
if (!args || TREE_CODE (args) != TREE_VEC)
1411114110
return false;
@@ -14154,8 +14153,8 @@ depset::hash::has_tu_local_tmpl_arg (tree decl, tree args, bool explain)
1415414153
/* Returns true if EXPR (part of the initializer for DECL) is a TU-local value
1415514154
or object. Emits an explanation if EXPLAIN is true. */
1415614155

14157-
bool
14158-
depset::hash::is_tu_local_value (tree decl, tree expr, bool explain)
14156+
static bool
14157+
is_tu_local_value (tree decl, tree expr, bool explain/*=false*/)
1415914158
{
1416014159
if (!expr)
1416114160
return false;
@@ -14208,6 +14207,63 @@ depset::hash::is_tu_local_value (tree decl, tree expr, bool explain)
1420814207
return false;
1420914208
}
1421014209

14210+
/* Complains if DECL is a TU-local entity imported from a named module.
14211+
Returns TRUE if instantiation should fail. */
14212+
14213+
bool
14214+
instantiating_tu_local_entity (tree decl)
14215+
{
14216+
if (!modules_p ())
14217+
return false;
14218+
14219+
if (TREE_CODE (decl) == TU_LOCAL_ENTITY)
14220+
{
14221+
auto_diagnostic_group d;
14222+
error ("instantiation exposes TU-local entity %qD",
14223+
TU_LOCAL_ENTITY_NAME (decl));
14224+
inform (TU_LOCAL_ENTITY_LOCATION (decl), "declared here");
14225+
return true;
14226+
}
14227+
14228+
/* Currently, only TU-local variables and functions will be emitted
14229+
from named modules. */
14230+
if (!VAR_OR_FUNCTION_DECL_P (decl))
14231+
return false;
14232+
14233+
/* From this point we will only be emitting warnings; if we're not
14234+
warning about this case then there's no need to check further. */
14235+
if (!warn_expose_global_module_tu_local
14236+
|| !warning_enabled_at (DECL_SOURCE_LOCATION (decl),
14237+
OPT_Wexpose_global_module_tu_local))
14238+
return false;
14239+
14240+
if (!is_tu_local_entity (decl))
14241+
return false;
14242+
14243+
tree origin = get_originating_module_decl (decl);
14244+
if (!DECL_LANG_SPECIFIC (origin)
14245+
|| !DECL_MODULE_IMPORT_P (origin))
14246+
return false;
14247+
14248+
/* Referencing TU-local entities from a header is generally OK.
14249+
We don't have an easy way to detect if this declaration came
14250+
from a header via a separate named module, but we can just
14251+
ignore that case for warning purposes. */
14252+
unsigned index = import_entity_index (origin);
14253+
module_state *mod = import_entity_module (index);
14254+
if (mod->is_header ())
14255+
return false;
14256+
14257+
auto_diagnostic_group d;
14258+
warning (OPT_Wexpose_global_module_tu_local,
14259+
"instantiation exposes TU-local entity %qD", decl);
14260+
inform (DECL_SOURCE_LOCATION (decl), "declared here");
14261+
14262+
/* We treat TU-local entities from the GMF as not actually being
14263+
TU-local as an extension, so allow instantation to proceed. */
14264+
return false;
14265+
}
14266+
1421114267
/* DECL is a newly discovered dependency. Create the depset, if it
1421214268
doesn't already exist. Add it to the worklist if so.
1421314269

@@ -14624,7 +14680,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_)
1462414680
return false;
1462514681

1462614682
bool internal_decl = false;
14627-
if (!header_module_p () && data->hash->is_tu_local_entity (decl))
14683+
if (!header_module_p () && is_tu_local_entity (decl))
1462814684
{
1462914685
/* A TU-local entity. For ADL we still need to create bindings
1463014686
for internal-linkage functions attached to a named module. */

gcc/cp/pt.cc

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9941,17 +9941,6 @@ add_pending_template (tree d)
99419941
pop_tinst_level ();
99429942
}
99439943

9944-
/* Emit a diagnostic about instantiating a reference to TU-local entity E. */
9945-
9946-
static void
9947-
complain_about_tu_local_entity (tree e)
9948-
{
9949-
auto_diagnostic_group d;
9950-
error ("instantiation exposes TU-local entity %qD",
9951-
TU_LOCAL_ENTITY_NAME (e));
9952-
inform (TU_LOCAL_ENTITY_LOCATION (e), "declared here");
9953-
}
9954-
99559944
/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
99569945
ARGLIST. Valid choices for FNS are given in the cp-tree.def
99579946
documentation for TEMPLATE_ID_EXPR. */
@@ -16614,12 +16603,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
1661416603
return t;
1661516604

1661616605
/* Any instantiation of a template containing a TU-local entity is an
16617-
exposure, so always issue a hard error irrespective of complain. */
16618-
if (TREE_CODE (t) == TU_LOCAL_ENTITY)
16619-
{
16620-
complain_about_tu_local_entity (t);
16621-
return error_mark_node;
16622-
}
16606+
exposure, so always issue a diagnostic irrespective of complain. */
16607+
if (instantiating_tu_local_entity (t))
16608+
return error_mark_node;
1662316609

1662416610
tsubst_flags_t tst_ok_flag = (complain & tf_tst_ok);
1662516611
complain &= ~tf_tst_ok;
@@ -20865,6 +20851,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
2086520851
tsubst_flags_t no_name_lookup_flag = (complain & tf_no_name_lookup);
2086620852
complain &= ~tf_no_name_lookup;
2086720853

20854+
if (instantiating_tu_local_entity (t))
20855+
RETURN (error_mark_node);
20856+
2086820857
if (!no_name_lookup_flag)
2086920858
if (tree d = maybe_dependent_member_ref (t, args, complain, in_decl))
2087020859
return d;
@@ -22507,11 +22496,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
2250722496
case OVERLOAD:
2250822497
if (modules_p ())
2250922498
for (tree ovl : lkp_range (t))
22510-
if (TREE_CODE (ovl) == TU_LOCAL_ENTITY)
22511-
{
22512-
complain_about_tu_local_entity (ovl);
22513-
RETURN (error_mark_node);
22514-
}
22499+
if (instantiating_tu_local_entity (ovl))
22500+
RETURN (error_mark_node);
2251522501
RETURN (t);
2251622502

2251722503
case TEMPLATE_DECL:
@@ -22791,10 +22777,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
2279122777
RETURN (op);
2279222778
}
2279322779

22794-
case TU_LOCAL_ENTITY:
22795-
complain_about_tu_local_entity (t);
22796-
RETURN (error_mark_node);
22797-
2279822780
default:
2279922781
/* Handle Objective-C++ constructs, if appropriate. */
2280022782
if (tree subst = objcp_tsubst_expr (t, args, complain, in_decl))

gcc/testsuite/g++.dg/modules/internal-17_b.C

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ import M;
2727
void test_usage() {
2828
a();
2929
b();
30-
c<int>();
31-
d<int>();
30+
c<int>(); // { dg-message "required from here" }
31+
d<int>(); // { dg-bogus "" }
3232
e();
33-
f<int>();
33+
f<int>(); // { dg-message "required from here" }
3434
g();
35-
h<int>();
35+
h<int>(); // { dg-bogus "" }
36+
37+
// { dg-warning "instantiation exposes TU-local entity" "" { target *-*-* } 0 }
3638
}
3739

3840
inline void expose() { // { dg-warning "exposes TU-local" }

0 commit comments

Comments
 (0)