PR c++/80891 (#3)
authorNathan Sidwell <nathan@acm.org>
Mon, 29 May 2017 12:52:58 +0000 (12:52 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 29 May 2017 12:52:58 +0000 (12:52 +0000)
PR c++/80891 (#3)
* cp-tree.h (build_min_nt_call_vec): Declare.
* decl.c (build_offset_ref_call_from_tree): Call it.
* parser.c (cp_parser_postfix_expression): Likewise.
* pt.c (tsubst_copy_and_build): Likewise.
* semantics.c (finish_call_expr): Likewise.
* tree.c (build_min_nt_loc): Keep unresolved lookups.
(build_min): Likewise.
(build_min_non_dep): Likewise.
(build_min_non_dep_call_vec): Likewise.
(build_min_nt_call_vec): New.

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

From-SVN: r248571

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr80891-3.C [new file with mode: 0644]

index 8f5dbc3f08b4db1e219f7c77ccb20be53440316f..67d86fa111445d7f36593d7155fa47c98ecd6126 100644 (file)
@@ -1,10 +1,24 @@
-2017-05-26  Nathan Sidwell  <nathan@acm.org>
+2017-05-29  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/80891 (#3)
+       * cp-tree.h (build_min_nt_call_vec): Declare.
+       * decl.c (build_offset_ref_call_from_tree): Call it.
+       * parser.c (cp_parser_postfix_expression): Likewise.
+       * pt.c (tsubst_copy_and_build): Likewise.
+       * semantics.c (finish_call_expr): Likewise.
+       * tree.c (build_min_nt_loc): Keep unresolved lookups.
+       (build_min): Likewise.
+       (build_min_non_dep): Likewise.
+       (build_min_non_dep_call_vec): Likewise.
+       (build_min_nt_call_vec): New.
 
        PR c++/80891 (#2)
        * tree.c (ovl_copy): Adjust assert, copy OVL_LOOKUP.
        (ovl_used): New.
        (lookup_keep): Call it.
 
+2017-05-26  Nathan Sidwell  <nathan@acm.org>
+
        Implement DR2061
        * name-lookup.c (push_inline_namespaces): New.
        (push_namespace): Look inside inline namespaces.
index a64e3ddd9890a9e17d120f5f9023f7aaf4104533..f1df0bd8dd796dace8b616bb3f02e0a0d39d41aa 100644 (file)
@@ -6891,6 +6891,7 @@ extern tree build_min_nt_loc                      (location_t, enum tree_code,
                                                 ...);
 extern tree build_min_non_dep                  (enum tree_code, tree, ...);
 extern tree build_min_non_dep_op_overload      (enum tree_code, tree, tree, ...);
+extern tree build_min_nt_call_vec (tree, vec<tree, va_gc> *);
 extern tree build_min_non_dep_call_vec         (tree, tree, vec<tree, va_gc> *);
 extern vec<tree, va_gc>* vec_copy_and_insert    (vec<tree, va_gc>*, tree, unsigned);
 extern tree build_cplus_new                    (tree, tree, tsubst_flags_t);
index 73eeb01fd75c07bc77877b527556f68f9244fb00..a095901be0950c2e66e3b4dc93315284541d3491 100644 (file)
@@ -4891,7 +4891,7 @@ build_offset_ref_call_from_tree (tree fn, vec<tree, va_gc> **args,
                  || TREE_CODE (fn) == MEMBER_REF);
       if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (*args))
-       return build_nt_call_vec (fn, *args);
+       return build_min_nt_call_vec (fn, *args);
 
       orig_args = make_tree_vector_copy (*args);
 
index 4f2c2d53294cd833f1e8ce3cdccc65621ff60266..313eebbc3d5fecd2c8787facafb67f3ef291431a 100644 (file)
@@ -6952,7 +6952,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  {
                    maybe_generic_this_capture (instance, fn);
                    postfix_expression
-                     = build_nt_call_vec (postfix_expression, args);
+                     = build_min_nt_call_vec (postfix_expression, args);
                    release_tree_vector (args);
                    break;
                  }
index 68514c911e95edf3a29e5511cc49270c622c1682..9c423366102440840e71197842135d754a33b089 100644 (file)
@@ -17389,7 +17389,7 @@ tsubst_copy_and_build (tree t,
                        && TREE_CODE (fn) != FIELD_DECL)
                    || type_dependent_expression_p (fn)
                    || any_type_dependent_arguments_p (call_args)))
-             ret = build_nt_call_vec (function, call_args);
+             ret = build_min_nt_call_vec (function, call_args);
            else if (!BASELINK_P (fn))
              ret = finish_call_expr (function, &call_args,
                                       /*disallow_virtual=*/false,
index df83d23c71351e8f149f7531a10f5ca21eff5ba9..87b95345d5cb53f348af007204f51b531783c417 100644 (file)
@@ -2322,7 +2322,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
       if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (*args))
        {
-         result = build_nt_call_vec (fn, *args);
+         result = build_min_nt_call_vec (fn, *args);
          SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
          KOENIG_LOOKUP_P (result) = koenig_p;
          if (is_overloaded_fn (fn))
index 9951b28d23de29648738bcc9b9756feec38274cd..37297d2a46542624db8e7c8b36a559a016ce04e8 100644 (file)
@@ -3216,13 +3216,14 @@ build_min_nt_loc (location_t loc, enum tree_code code, ...)
     {
       tree x = va_arg (p, tree);
       TREE_OPERAND (t, i) = x;
+      if (x && TREE_CODE (x) == OVERLOAD)
+       lookup_keep (x, true);
     }
 
   va_end (p);
   return t;
 }
 
-
 /* Similar to `build', but for template definitions.  */
 
 tree
@@ -3245,8 +3246,13 @@ build_min (enum tree_code code, tree tt, ...)
     {
       tree x = va_arg (p, tree);
       TREE_OPERAND (t, i) = x;
-      if (x && !TYPE_P (x) && TREE_SIDE_EFFECTS (x))
-       TREE_SIDE_EFFECTS (t) = 1;
+      if (x)
+       {
+         if (!TYPE_P (x) && TREE_SIDE_EFFECTS (x))
+           TREE_SIDE_EFFECTS (t) = 1;
+         if (TREE_CODE (x) == OVERLOAD)
+           lookup_keep (x, true);
+       }
     }
 
   va_end (p);
@@ -3281,6 +3287,8 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
     {
       tree x = va_arg (p, tree);
       TREE_OPERAND (t, i) = x;
+      if (x && TREE_CODE (x) == OVERLOAD)
+       lookup_keep (x, true);
     }
 
   if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
@@ -3292,14 +3300,34 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
   return convert_from_reference (t);
 }
 
-/* Similar to `build_nt_call_vec', but for template definitions of
+/* Similar to build_min_nt, but call expressions  */
+
+tree
+build_min_nt_call_vec (tree fn, vec<tree, va_gc> *args)
+{
+  tree ret, t;
+  unsigned int ix;
+
+  ret = build_vl_exp (CALL_EXPR, vec_safe_length (args) + 3);
+  CALL_EXPR_FN (ret) = fn;
+  CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+  FOR_EACH_VEC_SAFE_ELT (args, ix, t)
+    {
+      CALL_EXPR_ARG (ret, ix) = t;
+      if (TREE_CODE (t) == OVERLOAD)
+       lookup_keep (t, true);
+    }
+  return ret;
+}
+
+/* Similar to `build_min_nt_call_vec', but for template definitions of
    non-dependent expressions. NON_DEP is the non-dependent expression
    that has been built.  */
 
 tree
 build_min_non_dep_call_vec (tree non_dep, tree fn, vec<tree, va_gc> *argvec)
 {
-  tree t = build_nt_call_vec (fn, argvec);
+  tree t = build_min_nt_call_vec (fn, argvec);
   if (REFERENCE_REF_P (non_dep))
     non_dep = TREE_OPERAND (non_dep, 0);
   TREE_TYPE (t) = TREE_TYPE (non_dep);
index b3f6773594adad19f441ac85c711cd762e442cc0..d8603f8a8a3815ab2d345e39c693bd47420eae02 100644 (file)
@@ -1,5 +1,8 @@
 2017-05-29  Nathan Sidwell  <nathan@acm.org>
 
+       PR c++/80891 (#3)
+       * g++.dg/lookup/pr80891-3.C: New.
+
        PR c++/80891 (#2)
        * g++.dg/lookup/pr80891-2.C: New.
 
diff --git a/gcc/testsuite/g++.dg/lookup/pr80891-3.C b/gcc/testsuite/g++.dg/lookup/pr80891-3.C
new file mode 100644 (file)
index 0000000..e693a35
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/80891 part 3
+// We were failing to mark OVERLOADS held in template definitions as
+// immutable in non-call contexts.
+
+namespace std {
+  int endl();
+}
+
+using std::endl;
+
+template <class RealType> void test_spots(RealType)
+{
+  using namespace std;
+  RealType a;
+  a << endl;
+}
+
+template <typename T>
+void operator<< (T, int (&)());
+
+struct Q {};
+void test_maintest_method()
+{
+  Q q;
+  test_spots(q);
+}