2017-05-26 Nathan Sidwell <nathan@acm.org>
+ PR c++/80891 (#2)
+ * tree.c (ovl_copy): Adjust assert, copy OVL_LOOKUP.
+ (ovl_used): New.
+ (lookup_keep): Call it.
+
Implement DR2061
* name-lookup.c (push_inline_namespaces): New.
(push_namespace): Look inside inline namespaces.
else
result = make_node (OVERLOAD);
- gcc_assert (!OVL_NESTED_P (ovl) && !OVL_LOOKUP_P (ovl));
+ gcc_checking_assert (!OVL_NESTED_P (ovl) && OVL_USED_P (ovl));
TREE_TYPE (result) = TREE_TYPE (ovl);
OVL_FUNCTION (result) = OVL_FUNCTION (ovl);
OVL_CHAIN (result) = OVL_CHAIN (ovl);
OVL_HIDDEN_P (result) = OVL_HIDDEN_P (ovl);
OVL_USING_P (result) = OVL_USING_P (ovl);
+ OVL_LOOKUP_P (result) = OVL_LOOKUP_P (ovl);
return result;
}
return lookup_add (fns, lookup);
}
+/* Regular overload OVL is part of a kept lookup. Mark the nodes on
+ it as immutable. */
+
+static void
+ovl_used (tree ovl)
+{
+ for (;
+ ovl && TREE_CODE (ovl) == OVERLOAD
+ && !OVL_USED_P (ovl);
+ ovl = OVL_CHAIN (ovl))
+ {
+ gcc_checking_assert (!OVL_LOOKUP_P (ovl));
+ OVL_USED_P (ovl) = true;
+ }
+}
+
/* If KEEP is true, preserve the contents of a lookup so that it is
available for a later instantiation. Otherwise release the LOOKUP
nodes for reuse. */
&& OVL_LOOKUP_P (lookup) && !OVL_USED_P (lookup);
lookup = OVL_CHAIN (lookup))
if (keep)
- OVL_USED_P (lookup) = true;
+ {
+ OVL_USED_P (lookup) = true;
+ ovl_used (OVL_FUNCTION (lookup));
+ }
else
{
OVL_FUNCTION (lookup) = ovl_cache;
ovl_cache = lookup;
}
+
+ if (keep)
+ ovl_used (lookup);
}
/* Returns nonzero if X is an expression for a (possibly overloaded)
--- /dev/null
+// PR c++/80891 part 1
+// instantiation-time ADL for swap needs to copy a previous lookup
+// node, but gets confused.
+
+void swap();
+
+namespace boost {
+ void swap();
+}
+
+using namespace boost;
+
+template <typename T>
+void reversible_container_test ()
+{
+ using namespace boost;
+ T a;
+ swap (a);
+}
+
+namespace boost {
+ struct A {};
+ template <typename T> void swap(T);
+}
+
+void test_ptr_vector()
+{
+ reversible_container_test<A>;
+}