aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-11-10 00:00:00 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-11-10 00:00:00 -0500
commite19264356f11adf0fe3371d34c1ae158cc2a6e44 (patch)
tree43c24d939e59663e09fd327990242de217ec232f
parent9ab4c07adde40bba74646507b04b9c930cf560c0 (diff)
downloadgcc-e19264356f11adf0fe3371d34c1ae158cc2a6e44.zip
gcc-e19264356f11adf0fe3371d34c1ae158cc2a6e44.tar.gz
gcc-e19264356f11adf0fe3371d34c1ae158cc2a6e44.tar.bz2
DR 2007
DR 2007 * call.c (build_new_op_1): Don't do non-class lookup for =, -> or []. From-SVN: r217275
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c21
-rw-r--r--gcc/testsuite/g++.dg/template/operator14.C7
3 files changed, 29 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a831d62..f92e002 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 31864e9..bf191ca 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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
index 0000000..6267dbb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/operator14.C
@@ -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);