depset *add_dependency (tree decl, entity_kind);
void add_namespace_context (depset *, tree ns);
- private:
- bool has_tu_local_tmpl_arg (tree decl, tree args, bool explain);
- bool is_tu_local_entity (tree decl, bool explain = false);
- bool is_tu_local_value (tree decl, tree expr, bool explain = false);
-
private:
static bool add_binding_entity (tree, WMB_Flags, void *);
return slot ? *slot : NULL;
}
+static bool is_tu_local_entity (tree decl, bool explain = false);
+static bool is_tu_local_value (tree decl, tree expr, bool explain = false);
+static bool has_tu_local_tmpl_arg (tree decl, tree args, bool explain);
+
/* Returns true if DECL is a TU-local entity, as defined by [basic.link].
If EXPLAIN is true, emit an informative note about why DECL is TU-local. */
-bool
-depset::hash::is_tu_local_entity (tree decl, bool explain/*=false*/)
+static bool
+is_tu_local_entity (tree decl, bool explain/*=false*/)
{
gcc_checking_assert (DECL_P (decl));
location_t loc = DECL_SOURCE_LOCATION (decl);
/* Helper for is_tu_local_entity. Returns true if one of the ARGS of
DECL is TU-local. Emits an explanation if EXPLAIN is true. */
-bool
-depset::hash::has_tu_local_tmpl_arg (tree decl, tree args, bool explain)
+static bool
+has_tu_local_tmpl_arg (tree decl, tree args, bool explain)
{
if (!args || TREE_CODE (args) != TREE_VEC)
return false;
/* Returns true if EXPR (part of the initializer for DECL) is a TU-local value
or object. Emits an explanation if EXPLAIN is true. */
-bool
-depset::hash::is_tu_local_value (tree decl, tree expr, bool explain)
+static bool
+is_tu_local_value (tree decl, tree expr, bool explain/*=false*/)
{
if (!expr)
return false;
return false;
}
+/* Complains if DECL is a TU-local entity imported from a named module.
+ Returns TRUE if instantiation should fail. */
+
+bool
+instantiating_tu_local_entity (tree decl)
+{
+ if (!modules_p ())
+ return false;
+
+ if (TREE_CODE (decl) == TU_LOCAL_ENTITY)
+ {
+ auto_diagnostic_group d;
+ error ("instantiation exposes TU-local entity %qD",
+ TU_LOCAL_ENTITY_NAME (decl));
+ inform (TU_LOCAL_ENTITY_LOCATION (decl), "declared here");
+ return true;
+ }
+
+ /* Currently, only TU-local variables and functions will be emitted
+ from named modules. */
+ if (!VAR_OR_FUNCTION_DECL_P (decl))
+ return false;
+
+ /* From this point we will only be emitting warnings; if we're not
+ warning about this case then there's no need to check further. */
+ if (!warn_expose_global_module_tu_local
+ || !warning_enabled_at (DECL_SOURCE_LOCATION (decl),
+ OPT_Wexpose_global_module_tu_local))
+ return false;
+
+ if (!is_tu_local_entity (decl))
+ return false;
+
+ tree origin = get_originating_module_decl (decl);
+ if (!DECL_LANG_SPECIFIC (origin)
+ || !DECL_MODULE_IMPORT_P (origin))
+ return false;
+
+ /* Referencing TU-local entities from a header is generally OK.
+ We don't have an easy way to detect if this declaration came
+ from a header via a separate named module, but we can just
+ ignore that case for warning purposes. */
+ unsigned index = import_entity_index (origin);
+ module_state *mod = import_entity_module (index);
+ if (mod->is_header ())
+ return false;
+
+ auto_diagnostic_group d;
+ warning (OPT_Wexpose_global_module_tu_local,
+ "instantiation exposes TU-local entity %qD", decl);
+ inform (DECL_SOURCE_LOCATION (decl), "declared here");
+
+ /* We treat TU-local entities from the GMF as not actually being
+ TU-local as an extension, so allow instantation to proceed. */
+ return false;
+}
+
/* DECL is a newly discovered dependency. Create the depset, if it
doesn't already exist. Add it to the worklist if so.
return false;
bool internal_decl = false;
- if (!header_module_p () && data->hash->is_tu_local_entity (decl))
+ if (!header_module_p () && is_tu_local_entity (decl))
{
/* A TU-local entity. For ADL we still need to create bindings
for internal-linkage functions attached to a named module. */
pop_tinst_level ();
}
-/* Emit a diagnostic about instantiating a reference to TU-local entity E. */
-
-static void
-complain_about_tu_local_entity (tree e)
-{
- auto_diagnostic_group d;
- error ("instantiation exposes TU-local entity %qD",
- TU_LOCAL_ENTITY_NAME (e));
- inform (TU_LOCAL_ENTITY_LOCATION (e), "declared here");
-}
-
/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
ARGLIST. Valid choices for FNS are given in the cp-tree.def
documentation for TEMPLATE_ID_EXPR. */
return t;
/* Any instantiation of a template containing a TU-local entity is an
- exposure, so always issue a hard error irrespective of complain. */
- if (TREE_CODE (t) == TU_LOCAL_ENTITY)
- {
- complain_about_tu_local_entity (t);
- return error_mark_node;
- }
+ exposure, so always issue a diagnostic irrespective of complain. */
+ if (instantiating_tu_local_entity (t))
+ return error_mark_node;
tsubst_flags_t tst_ok_flag = (complain & tf_tst_ok);
complain &= ~tf_tst_ok;
tsubst_flags_t no_name_lookup_flag = (complain & tf_no_name_lookup);
complain &= ~tf_no_name_lookup;
+ if (instantiating_tu_local_entity (t))
+ RETURN (error_mark_node);
+
if (!no_name_lookup_flag)
if (tree d = maybe_dependent_member_ref (t, args, complain, in_decl))
return d;
case OVERLOAD:
if (modules_p ())
for (tree ovl : lkp_range (t))
- if (TREE_CODE (ovl) == TU_LOCAL_ENTITY)
- {
- complain_about_tu_local_entity (ovl);
- RETURN (error_mark_node);
- }
+ if (instantiating_tu_local_entity (ovl))
+ RETURN (error_mark_node);
RETURN (t);
case TEMPLATE_DECL:
RETURN (op);
}
- case TU_LOCAL_ENTITY:
- complain_about_tu_local_entity (t);
- RETURN (error_mark_node);
-
default:
/* Handle Objective-C++ constructs, if appropriate. */
if (tree subst = objcp_tsubst_expr (t, args, complain, in_decl))