From 5e08432ed0c87fe0e2a6b144e1f87b7615a08d46 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 14 Jul 2003 19:05:05 +0000 Subject: [PATCH] re PR c++/7019 ([3.3 only] SFINAE does not work with explicitally specified template arguments) PR c++/7019 * cp-tree.h (lookup_qualified_name): Adjust prototype. * decl.c (lookup_qualified_name): Add complain parameter. Adjust call to is_aggr_type. * parser.c (cp_parser_lookup_name): Adjust call to lookup_qualified_name. * pt.c (tsubst_qualified_id): Likewise. (tsubst_copy_and_build): Likewise. * semantics.c (finish_qualified_id_expr): Deal with erroneous expressions. PR c++/7019 * g++.dg/template/overload2.C: New test. From-SVN: r69342 --- gcc/cp/ChangeLog | 13 ++++++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 26 ++++++++++++++--------- gcc/cp/parser.c | 3 ++- gcc/cp/pt.c | 12 ++++++----- gcc/cp/semantics.c | 3 +++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/overload2.C | 15 +++++++++++++ 8 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/overload2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8318b914020..e84ea849f81 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2003-07-14 Mark Mitchell + + PR c++/7019 + * cp-tree.h (lookup_qualified_name): Adjust prototype. + * decl.c (lookup_qualified_name): Add complain parameter. Adjust + call to is_aggr_type. + * parser.c (cp_parser_lookup_name): Adjust call to + lookup_qualified_name. + * pt.c (tsubst_qualified_id): Likewise. + (tsubst_copy_and_build): Likewise. + * semantics.c (finish_qualified_id_expr): Deal with erroneous + expressions. + 2003-07-14 Gabriel Dos Reis PR c++/11510 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8658be6d93a..acc4528f9ef 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3679,7 +3679,7 @@ extern tree make_typename_type (tree, tree, tsubst_flags_t); extern tree make_unbound_class_template (tree, tree, tsubst_flags_t); extern tree lookup_name_nonclass (tree); extern tree lookup_function_nonclass (tree, tree); -extern tree lookup_qualified_name (tree, tree, bool); +extern tree lookup_qualified_name (tree, tree, bool, bool); extern tree lookup_name (tree, int); extern tree lookup_name_current_level (tree); extern tree lookup_type_current_level (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d4c212f3e76..2daaee60c0e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5761,10 +5761,12 @@ qualify_lookup (tree val, int flags) bindings. Returns a DECL (or OVERLOAD, or BASELINK) representing the - declaration found. */ + declaration found. If no suitable declaration can be found, + ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is + neither a class-type nor a namespace a diagnostic is issued. */ tree -lookup_qualified_name (tree scope, tree name, bool is_type_p) +lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) { int flags = 0; @@ -5776,15 +5778,19 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p) flags |= LOOKUP_COMPLAIN; if (is_type_p) flags |= LOOKUP_PREFER_TYPES; - if (!qualified_lookup_using_namespace (name, scope, &binding, - flags)) - return NULL_TREE; - return select_decl (&binding, flags); + if (qualified_lookup_using_namespace (name, scope, &binding, + flags)) + return select_decl (&binding, flags); } - else if (is_aggr_type (scope, /*or_else=*/1)) - return lookup_member (scope, name, 0, is_type_p); - else - return error_mark_node; + else if (is_aggr_type (scope, complain)) + { + tree t; + t = lookup_member (scope, name, 0, is_type_p); + if (t) + return t; + } + + return error_mark_node; } /* Check to see whether or not DECL is a variable that would have been diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 98411a6abdb..bfce0ca8d34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12825,7 +12825,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name, may be instantiated during name lookup. In that case, errors may be issued. Even if we rollback the current tentative parse, those errors are valid. */ - decl = lookup_qualified_name (parser->scope, name, is_type); + decl = lookup_qualified_name (parser->scope, name, is_type, + /*complain=*/true); if (dependent_p) pop_scope (parser->scope); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ee9d2459d7e..1f7822ca72b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7149,9 +7149,9 @@ tsubst_qualified_id (tree qualified_id, tree args, } else expr = name; - if (!BASELINK_P (name) - && !DECL_P (expr)) - expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0); + if (!BASELINK_P (name) && !DECL_P (expr)) + expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, + (complain & tf_error) != 0); if (DECL_P (expr)) check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, @@ -7611,7 +7611,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) scope = tsubst_expr (scope, args, complain, in_decl); do_local_using_decl (lookup_qualified_name (scope, name, - /*is_type_p=*/0)); + /*is_type_p=*/0, + /*complain=*/true)); } else { @@ -8285,7 +8286,8 @@ tsubst_copy_and_build (tree t, args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, - /*is_type=*/0); + /*is_type=*/0, + /*complain=*/true); if (BASELINK_P (member)) BASELINK_FUNCTIONS (member) = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ab9376b48a6..9a9ae20e1be 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1343,6 +1343,9 @@ tree finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, bool address_p) { + if (error_operand_p (expr)) + return error_mark_node; + /* If EXPR occurs as the operand of '&', use special handling that permits a pointer-to-member. */ if (address_p && done) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c279efebd63..9a4b06245eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-07-14 Mark Mitchell + + PR c++/7019 + * g++.dg/template/overload2.C: New test. + 2003-07-14 Franz Sirl PR optimization/11440 diff --git a/gcc/testsuite/g++.dg/template/overload2.C b/gcc/testsuite/g++.dg/template/overload2.C new file mode 100644 index 00000000000..253d055cdf6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload2.C @@ -0,0 +1,15 @@ +template struct foo; + +template +int f(foo*); + +template +char* f(...); + +struct X { int ob_type; }; +struct Y { char* ob_type; }; + int x = f(0); +char* y = f(0); +char* z = f(0); + +int main() { return 0; } -- 2.30.2