DR 2007
authorJason Merrill <jason@redhat.com>
Mon, 10 Nov 2014 05:00:00 +0000 (00:00 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 10 Nov 2014 05:00:00 +0000 (00:00 -0500)
DR 2007
* call.c (build_new_op_1): Don't do non-class lookup for =, -> or [].

From-SVN: r217275

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/template/operator14.C [new file with mode: 0644]

index a831d62d8c2073b3447125572cd384a987019f0c..f92e002d19ac56409049c592ed2c6e2881aee728 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-09  Jason Merrill  <jason@redhat.com>
+
+       DR 2007
+       * call.c (build_new_op_1): Don't do non-class lookup for =, -> or [].
+
 2014-11-07  Jason Merrill  <jason@redhat.com>
 
        DR 1558
index 31864e902d8729794ac111389a9a8174a8486005..bf191cadfd476d5977309524e45e3c6cf506fc94 100644 (file)
@@ -5309,6 +5309,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
 
   arg1 = prep_operand (arg1);
 
+  bool memonly = false;
   switch (code)
     {
     case NEW_EXPR:
@@ -5340,6 +5341,16 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
       code_orig_arg1 = TREE_CODE (TREE_TYPE (arg1));
       code_orig_arg2 = TREE_CODE (TREE_TYPE (arg2));
       break;
+
+      /* =, ->, [], () must be non-static member functions.  */
+    case MODIFY_EXPR:
+      if (code2 != NOP_EXPR)
+       break;
+    case COMPONENT_REF:
+    case ARRAY_REF:
+      memonly = true;
+      break;
+
     default:
       break;
     }
@@ -5369,10 +5380,12 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
 
   /* Add namespace-scope operators to the list of functions to
      consider.  */
-  add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
-                 NULL_TREE, arglist, NULL_TREE,
-                 NULL_TREE, false, NULL_TREE, NULL_TREE,
-                 flags, &candidates, complain);
+  if (!memonly)
+    add_candidates (lookup_function_nonclass (fnname, arglist,
+                                             /*block_p=*/true),
+                   NULL_TREE, arglist, NULL_TREE,
+                   NULL_TREE, false, NULL_TREE, NULL_TREE,
+                   flags, &candidates, complain);
 
   args[0] = arg1;
   args[1] = arg2;
diff --git a/gcc/testsuite/g++.dg/template/operator14.C b/gcc/testsuite/g++.dg/template/operator14.C
new file mode 100644 (file)
index 0000000..6267dbb
--- /dev/null
@@ -0,0 +1,7 @@
+// DR 2007
+// We shouldn't instantiate A<void> to lookup operator=, since operator=
+// must be a non-static member function.
+
+template<typename T> struct A { typename T::error e; };
+template<typename T> struct B { };
+B<A<void> > b1, &b2 = (b1 = b1);