PR c++/80891 (#2)
authorNathan Sidwell <nathan@acm.org>
Mon, 29 May 2017 11:51:13 +0000 (11:51 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 29 May 2017 11:51:13 +0000 (11:51 +0000)
PR c++/80891 (#2)
* tree.c (ovl_copy): Adjust assert, copy OVL_LOOKUP.
(ovl_used): New.
(lookup_keep): Call it.

PR c++/80891 (#2)
* g++.dg/lookup/pr80891-2.C: New.

From-SVN: r248570

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr80891-2.C [new file with mode: 0644]

index 8e3530fb4409877d6e58b7bc49c1d660e7bdc9dc..8f5dbc3f08b4db1e219f7c77ccb20be53440316f 100644 (file)
@@ -1,5 +1,10 @@
 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.
index 343708f430232ce564bad346cdf6648932e41aba..9951b28d23de29648738bcc9b9756feec38274cd 100644 (file)
@@ -2139,12 +2139,13 @@ ovl_copy (tree ovl)
   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;
 }
@@ -2395,6 +2396,22 @@ lookup_maybe_add (tree fns, tree lookup)
   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.  */
@@ -2407,12 +2424,18 @@ lookup_keep (tree lookup, bool keep)
         && 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)
index accf635d258287c78511e644937f6a2ba29ad479..b3f6773594adad19f441ac85c711cd762e442cc0 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-29  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/80891 (#2)
+       * g++.dg/lookup/pr80891-2.C: New.
+
 2017-05-29  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/37131
diff --git a/gcc/testsuite/g++.dg/lookup/pr80891-2.C b/gcc/testsuite/g++.dg/lookup/pr80891-2.C
new file mode 100644 (file)
index 0000000..fa48b0b
--- /dev/null
@@ -0,0 +1,29 @@
+// 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>;
+}