diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-07-14 19:05:05 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-07-14 19:05:05 +0000 |
commit | 5e08432ed0c87fe0e2a6b144e1f87b7615a08d46 (patch) | |
tree | cf301c886bb9f86fa5fd71ba555a1ae37357e0b2 | |
parent | bda243ec50619e4b80e35a8c77a9ebc44647ca38 (diff) | |
download | gcc-5e08432ed0c87fe0e2a6b144e1f87b7615a08d46.zip gcc-5e08432ed0c87fe0e2a6b144e1f87b7615a08d46.tar.gz gcc-5e08432ed0c87fe0e2a6b144e1f87b7615a08d46.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 26 | ||||
-rw-r--r-- | gcc/cp/parser.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 12 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/overload2.C | 15 |
8 files changed, 62 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8318b91..e84ea84 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2003-07-14 Mark Mitchell <mark@codesourcery.com> + + 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 <gdr@integrable-solutions.net> PR c++/11510 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8658be6..acc4528 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 d4c212f..2daaee6 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 98411a6..bfce0ca 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 ee9d245..1f7822c 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 ab9376b..9a9ae20 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 c279efe..9a4b062 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-07-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/7019 + * g++.dg/template/overload2.C: New test. + 2003-07-14 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> 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 0000000..253d055 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload2.C @@ -0,0 +1,15 @@ +template <class T, int (T::*)> struct foo; + +template <class T> +int f(foo<T,&T::ob_type>*); + +template <class T> +char* f(...); + +struct X { int ob_type; }; +struct Y { char* ob_type; }; + int x = f<X>(0); +char* y = f<Y>(0); +char* z = f<int>(0); + +int main() { return 0; } |