aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-08-18 11:36:40 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-08-20 17:14:11 +1000
commit6f115a8eeea41d383dfb1bbb1af6ac9a97aee180 (patch)
tree7515e1d1a7735749ce8edc56b19125bb5e0a4f79 /gcc/cp
parent0b7904e274fbd6a736d63c0fed28ea32f9cb5997 (diff)
downloadgcc-6f115a8eeea41d383dfb1bbb1af6ac9a97aee180.zip
gcc-6f115a8eeea41d383dfb1bbb1af6ac9a97aee180.tar.gz
gcc-6f115a8eeea41d383dfb1bbb1af6ac9a97aee180.tar.bz2
c++/modules: Handle transitive reachability for deduction guides [PR116403]
Currently we implement [temp.deduct.guide] p1 by forcing all deduction guides to be considered as exported. However this is not sufficient: for transitive non-exported imports we will still hide the deduction guide from name lookup, causing errors. This patch instead adjusts name lookup to have a new ANY_REACHABLE flag to allow for this case. Currently this is only used by deduction guides but there are some other circumstances where this may be useful in the future (e.g. finding existing temploid friends). PR c++/116403 gcc/cp/ChangeLog: * pt.cc (deduction_guides_for): Use ANY_REACHABLE for lookup of deduction guides. * module.cc (depset::hash::add_deduction_guides): Likewise. (module_state::write_cluster): No longer override deduction guides as exported. * name-lookup.cc (name_lookup::search_namespace_only): Ignore visibility when LOOK_want::ANY_REACHABLE is specified. (check_module_override): Ignore visibility when checking for ambiguating deduction guides. * name-lookup.h (LOOK_want): New flag 'ANY_REACHABLE'. gcc/testsuite/ChangeLog: * g++.dg/modules/dguide-4_a.C: New test. * g++.dg/modules/dguide-4_b.C: New test. * g++.dg/modules/dguide-4_c.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/module.cc7
-rw-r--r--gcc/cp/name-lookup.cc38
-rw-r--r--gcc/cp/name-lookup.h5
-rw-r--r--gcc/cp/pt.cc3
4 files changed, 37 insertions, 16 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 0a4ceff..ce0ba69 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13645,7 +13645,7 @@ depset::hash::add_deduction_guides (tree decl)
if (find_binding (ns, name))
return;
- tree guides = lookup_qualified_name (ns, name, LOOK_want::NORMAL,
+ tree guides = lookup_qualified_name (ns, name, LOOK_want::ANY_REACHABLE,
/*complain=*/false);
if (guides == error_mark_node)
return;
@@ -15228,11 +15228,6 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
flags |= cbf_hidden;
else if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (bound)))
flags |= cbf_export;
- else if (deduction_guide_p (bound))
- /* Deduction guides are always exported so that they are
- visible to name lookup whenever their class template
- is reachable. */
- flags |= cbf_export;
}
gcc_checking_assert (DECL_P (bound));
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 872f1af..70ad4cb 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -916,7 +916,8 @@ name_lookup::search_namespace_only (tree scope)
if (unsigned base = cluster->indices[jx].base)
if (unsigned span = cluster->indices[jx].span)
do
- if (bitmap_bit_p (imports, base))
+ if (bool (want & LOOK_want::ANY_REACHABLE)
+ || bitmap_bit_p (imports, base))
goto found;
while (++base, --span);
continue;
@@ -960,9 +961,17 @@ name_lookup::search_namespace_only (tree scope)
dup_detect |= dup;
}
- if (STAT_TYPE_VISIBLE_P (bind))
- type = STAT_TYPE (bind);
- bind = STAT_VISIBLE (bind);
+ if (bool (want & LOOK_want::ANY_REACHABLE))
+ {
+ type = STAT_TYPE (bind);
+ bind = STAT_DECL (bind);
+ }
+ else
+ {
+ if (STAT_TYPE_VISIBLE_P (bind))
+ type = STAT_TYPE (bind);
+ bind = STAT_VISIBLE (bind);
+ }
}
/* And process it. */
@@ -3761,6 +3770,10 @@ check_module_override (tree decl, tree mvec, bool hiding,
tree nontmpl = STRIP_TEMPLATE (decl);
bool attached = DECL_LANG_SPECIFIC (nontmpl) && DECL_MODULE_ATTACH_P (nontmpl);
+ /* For deduction guides we don't do normal name lookup, but rather consider
+ any reachable declaration, so we should check for overriding here too. */
+ bool any_reachable = deduction_guide_p (decl);
+
if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED)
{
cluster++;
@@ -3775,7 +3788,8 @@ check_module_override (tree decl, tree mvec, bool hiding,
continue;
if (!cluster->indices[jx].base)
continue;
- if (!bitmap_bit_p (imports, cluster->indices[jx].base))
+ if (!any_reachable
+ && !bitmap_bit_p (imports, cluster->indices[jx].base))
continue;
/* Is it loaded? */
if (cluster->slots[jx].is_lazy ())
@@ -3795,9 +3809,17 @@ check_module_override (tree decl, tree mvec, bool hiding,
/* If there was a matching STAT_TYPE here then xref_tag
should have found it, but we need to check anyway because
a conflicting using-declaration may exist. */
- if (STAT_TYPE_VISIBLE_P (bind))
- type = STAT_TYPE (bind);
- bind = STAT_VISIBLE (bind);
+ if (any_reachable)
+ {
+ type = STAT_TYPE (bind);
+ bind = STAT_DECL (bind);
+ }
+ else
+ {
+ if (STAT_TYPE_VISIBLE_P (bind))
+ type = STAT_TYPE (bind);
+ bind = STAT_VISIBLE (bind);
+ }
}
if (type)
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 7c41934..f39f530 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -385,9 +385,12 @@ enum class LOOK_want
TYPE = 1 << 1, /* We only want TYPE_DECLS. */
NAMESPACE = 1 << 2, /* We only want NAMESPACE_DECLS. */
- HIDDEN_FRIEND = 1 << 3, /* See hidden friends. */
+ HIDDEN_FRIEND = 1 << 3, /* See hidden friends. */
HIDDEN_LAMBDA = 1 << 4, /* See lambda-ignored entities. */
+ ANY_REACHABLE = 1 << 5, /* Include reachable module declarations not
+ normally visible to name lookup. */
+
TYPE_NAMESPACE = TYPE | NAMESPACE, /* Either NAMESPACE or TYPE. */
};
constexpr LOOK_want operator| (LOOK_want a, LOOK_want b)
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 76edc7a..ea660a5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -30743,7 +30743,8 @@ deduction_guides_for (tree tmpl, bool &any_dguides_p, tsubst_flags_t complain)
{
guides = lookup_qualified_name (CP_DECL_CONTEXT (tmpl),
dguide_name (tmpl),
- LOOK_want::NORMAL, /*complain*/false);
+ LOOK_want::ANY_REACHABLE,
+ /*complain=*/false);
if (guides == error_mark_node)
guides = NULL_TREE;
else