From 676e33ca810aa9f33fd233c75d845638e4755c0d Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 2 Mar 2004 02:06:18 +0000 Subject: [PATCH] re PR c++/14360 (Overeager argument dependent name lookup) PR c++/14360 * parser.c (cp_parser_postfix_expression): Do not perform Koenig lookup if ordinary name-lookup finds a non-function. * pt.c (tsubst_copy_and_build): Likewise. PR c++/14361 * parser.c (cp_parser_late_parsing_default_args): Check that there are no extra tokens after the end of the default-argument expression. PR c++/14360 * g++.old-deja/g++.ns/koenig5.C: Remove some error markers. PR c++/14361 * g++.dg/parse/defarg7.C: New test. PR c++/14359 * g++.dg/template/friend26.C: New test. From-SVN: r78739 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/parser.c | 10 +++++++++- gcc/cp/pt.c | 6 ++++-- gcc/testsuite/ChangeLog | 11 +++++++++++ gcc/testsuite/g++.dg/parse/defarg7.C | 5 +++++ gcc/testsuite/g++.dg/template/friend26.C | 15 +++++++++++++++ gcc/testsuite/g++.old-deja/g++.ns/koenig5.C | 8 +++++--- 7 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/defarg7.C create mode 100644 gcc/testsuite/g++.dg/template/friend26.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 02b99e44b308..21b0172d2c41 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -3,6 +3,18 @@ PR c++/14369 * error.c (dump_expr): Handle THROW_EXPR. +2004-03-01 Mark Mitchell + + PR c++/14360 + * parser.c (cp_parser_postfix_expression): Do not perform Koenig + lookup if ordinary name-lookup finds a non-function. + * pt.c (tsubst_copy_and_build): Likewise. + + PR c++/14361 + * parser.c (cp_parser_late_parsing_default_args): Check that there + are no extra tokens after the end of the default-argument + expression. + 2004-03-01 Mark Mitchell PR c++/14324 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 77b57957f791..9184f0ea1db4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3810,9 +3810,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) koenig_p = false; if (idk == CP_ID_KIND_UNQUALIFIED) { + /* We do not perform argument-dependent lookup if + normal lookup finds a non-function, in accordance + with the expected resolution of DR 218. */ if (args && (is_overloaded_fn (postfix_expression) - || DECL_P (postfix_expression) || TREE_CODE (postfix_expression) == IDENTIFIER_NODE)) { koenig_p = true; @@ -14757,6 +14759,12 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) if (DECL_CLASS_SCOPE_P (fn)) pop_nested_class (); + /* If the token stream has not been completely used up, then + there was extra junk after the end of the default + argument. */ + if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF)) + cp_parser_error (parser, "expected `,'"); + /* Restore saved state. */ parser->lexer = saved_lexer; parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 20056eb8e759..8f9a7bdc4c43 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8361,10 +8361,12 @@ tsubst_copy_and_build (tree t, } call_args = RECUR (TREE_OPERAND (t, 1)); - + + /* We do not perform argument-dependent lookup if normal + lookup finds a non-function, in accordance with the + expected resolution of DR 218. */ if (koenig_p && (is_overloaded_fn (function) - || DECL_P (function) || TREE_CODE (function) == IDENTIFIER_NODE)) function = perform_koenig_lookup (function, call_args); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 459ff6600ad4..b2df61fec54e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2004-03-01 Mark Mitchell + + PR c++/14360 + * g++.old-deja/g++.ns/koenig5.C: Remove some error markers. + + PR c++/14361 + * g++.dg/parse/defarg7.C: New test. + + PR c++/14359 + * g++.dg/template/friend26.C: New test. + 2004-03-01 Mark Mitchell PR c++/14324 diff --git a/gcc/testsuite/g++.dg/parse/defarg7.C b/gcc/testsuite/g++.dg/parse/defarg7.C new file mode 100644 index 000000000000..c1f75ce8f18e --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/defarg7.C @@ -0,0 +1,5 @@ +// PR c++/14361 + +class A { + A ( int n=0 int n ); // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/friend26.C b/gcc/testsuite/g++.dg/template/friend26.C new file mode 100644 index 000000000000..3cf659df402c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend26.C @@ -0,0 +1,15 @@ +// PR c++/14359 + +template struct A {}; + +template struct B +{ + template friend void foo(const A& a, const B&) { a; } +}; + +void bar() +{ + A a; + B b; + foo(a,b); +} diff --git a/gcc/testsuite/g++.old-deja/g++.ns/koenig5.C b/gcc/testsuite/g++.old-deja/g++.ns/koenig5.C index 84af9f1edf5a..d84fc8dbf41f 100644 --- a/gcc/testsuite/g++.old-deja/g++.ns/koenig5.C +++ b/gcc/testsuite/g++.old-deja/g++.ns/koenig5.C @@ -1,16 +1,18 @@ // { dg-do assemble } // To find function pointers in Koenig lookup is ok as long as we only find one. namespace A{ - void foo(); // { dg-error "" } + void foo(); struct X{}; void (*bar)(X*)=0; } using A::X; -void (*foo)(X*)=0; // { dg-error "" } +void (*foo)(X*)=0; void g() { - foo(new X); // { dg-error "" } both objects and functions found + foo(new X); // ok -- DR 218 says that we find the global + // foo variable first, and therefore do not + // perform argument-dependent lookup. bar(new X); // ok } -- 2.43.5