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;
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));
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;
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. */
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++;
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 ())
/* 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)
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)
{
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
--- /dev/null
+// PR c++/116403
+// { dg-additional-options "-fmodules-ts -Wno-global-module" }
+// { dg-module-cmi A }
+
+module;
+
+template <typename T> struct GMF {
+ GMF(int);
+};
+GMF(int) -> GMF<int>;
+
+export module A;
+export using ::GMF;
+
+export template <typename T> struct Attached {
+ Attached(int);
+};
+Attached(int) -> Attached<int>;
--- /dev/null
+// PR c++/116403
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi B }
+
+export module B;
+import A; // not exported
+
+export using ::GMF;
+export using ::Attached;
--- /dev/null
+// PR c++/116403
+// { dg-additional-options "-fmodules-ts" }
+
+import B;
+
+int main() {
+ GMF gmf(123);
+ GMF<int> test_gmf = gmf;
+
+ Attached attached(456);
+ Attached<int> test_attached = attached;
+}
+
+GMF(int) -> GMF<double>; // { dg-error "ambiguating" }
+Attached(int) -> Attached<double>; // { dg-error "ambiguating" }