From e19264356f11adf0fe3371d34c1ae158cc2a6e44 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 10 Nov 2014 00:00:00 -0500 Subject: [PATCH] DR 2007 DR 2007 * call.c (build_new_op_1): Don't do non-class lookup for =, -> or []. From-SVN: r217275 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/call.c | 21 +++++++++++++++++---- gcc/testsuite/g++.dg/template/operator14.C | 7 +++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/operator14.C 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 + + DR 2007 + * call.c (build_new_op_1): Don't do non-class lookup for =, -> or []. + 2014-11-07 Jason Merrill 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 to lookup operator=, since operator= +// must be a non-static member function. + +template struct A { typename T::error e; }; +template struct B { }; +B > b1, &b2 = (b1 = b1); -- 2.7.4