diff options
author | Jason Merrill <jason@redhat.com> | 2011-05-20 14:01:22 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-05-20 14:01:22 -0400 |
commit | 94df301fa033641561145d44ed48cf4c85d43a2c (patch) | |
tree | a133483f2142f1c02de48fd4af4865636ad9ed75 /gcc | |
parent | 6e04dcd56f7d94288467234f065fca6006761cfe (diff) | |
download | gcc-94df301fa033641561145d44ed48cf4c85d43a2c.zip gcc-94df301fa033641561145d44ed48cf4c85d43a2c.tar.gz gcc-94df301fa033641561145d44ed48cf4c85d43a2c.tar.bz2 |
re PR c++/24163 (dependent Base class scope examined during unqualified name lookup in template)
PR c++/24163
PR c++/29131
gcc/cp/
* pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating
unqualified lookup.
* semantics.c (perform_koenig_lookup): Add complain parm.
* cp-tree.h: Adjust.
* parser.c (cp_parser_postfix_expression): Adjust.
(cp_parser_perform_range_for_lookup): Adjust.
libstdc++-v3/
* include/ext/pb_ds/assoc_container.hpp: Explicitly qualify calls to
functions from dependent bases.
* include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/rb_tree_map_/
split_join_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/splay_tree_/
split_join_fn_imps.hpp: Likewise.
* include/ext/pb_ds/detail/tree_policy/
order_statistics_imp.hpp: Likewise.
* include/ext/pb_ds/detail/trie_policy/
prefix_search_node_update_imp.hpp: Likewise.
* include/ext/rc_string_base.h: Likewise.
* include/ext/rope: Likewise.
* include/ext/ropeimpl.h: Likewise.
* testsuite/util/exception/safety.h: Likewise.
* testsuite/util/native_type/native_priority_queue.hpp: Likewise.
* testsuite/util/testsuite_io.h: Likewise.
* include/std/functional: Declare mem_fn earlier.
* include/tr1/functional: Likewise.
* include/tr1/exp_integral.tcc: Declare __expint_E1 earlier.
From-SVN: r173965
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/cp/pt.c | 69 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr47615.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/overload/defarg1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tc1/dr213.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/koenig9.C | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr34850.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr39362.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.brendan/crash56.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C | 2 |
14 files changed, 149 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 61adf5f..5d93472 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 2011-05-20 Jason Merrill <jason@redhat.com> + PR c++/24163 + PR c++/29131 + * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating + unqualified lookup. + * semantics.c (perform_koenig_lookup): Add complain parm. + * cp-tree.h: Adjust. + * parser.c (cp_parser_postfix_expression): Adjust. + (cp_parser_perform_range_for_lookup): Adjust. + +2011-05-20 Jason Merrill <jason@redhat.com> + * semantics.c (finish_call_expr): SET_EXPR_LOCATION. 2011-05-20 Joseph Myers <joseph@codesourcery.com> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3ccbfda..ada01fb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5365,7 +5365,8 @@ extern tree finish_stmt_expr_expr (tree, tree); extern tree finish_stmt_expr (tree, bool); extern tree stmt_expr_value_expr (tree); bool empty_expr_stmt_p (tree); -extern tree perform_koenig_lookup (tree, VEC(tree,gc) *, bool); +extern tree perform_koenig_lookup (tree, VEC(tree,gc) *, bool, + tsubst_flags_t); extern tree finish_call_expr (tree, VEC(tree,gc) **, bool, bool, tsubst_flags_t); extern tree finish_increment_expr (tree, enum tree_code); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cf9286a..2b45260 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5019,7 +5019,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (!any_type_dependent_arguments_p (args)) postfix_expression = perform_koenig_lookup (postfix_expression, args, - /*include_std=*/false); + /*include_std=*/false, + tf_warning_or_error); } else postfix_expression @@ -5044,7 +5045,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (!any_type_dependent_arguments_p (args)) postfix_expression = perform_koenig_lookup (postfix_expression, args, - /*include_std=*/false); + /*include_std=*/false, + tf_warning_or_error); } } } @@ -8741,11 +8743,13 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end) VEC_safe_push (tree, gc, vec, range); member_begin = perform_koenig_lookup (id_begin, vec, - /*include_std=*/true); + /*include_std=*/true, + tf_warning_or_error); *begin = finish_call_expr (member_begin, &vec, false, true, tf_warning_or_error); member_end = perform_koenig_lookup (id_end, vec, - /*include_std=*/true); + /*include_std=*/true, + tf_warning_or_error); *end = finish_call_expr (member_end, &vec, false, true, tf_warning_or_error); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 75d0674..d72596f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12894,6 +12894,20 @@ tsubst_copy_and_build (tree t, /*done=*/false, /*address_p=*/false); } + else if (koenig_p && TREE_CODE (function) == IDENTIFIER_NODE) + { + /* Do nothing; calling tsubst_copy_and_build on an identifier + would incorrectly perform unqualified lookup again. + + Note that we can also have an IDENTIFIER_NODE if the earlier + unqualified lookup found a member function; in that case + koenig_p will be false and we do want to do the lookup + again to find the instantiated member function. + + FIXME but doing that causes c++/15272, so we need to stop + using IDENTIFIER_NODE in that situation. */ + qualified_p = false; + } else { if (TREE_CODE (function) == COMPONENT_REF) @@ -12965,14 +12979,59 @@ tsubst_copy_and_build (tree t, into a non-dependent call. */ && type_dependent_expression_p_push (t) && !any_type_dependent_arguments_p (call_args)) - function = perform_koenig_lookup (function, call_args, false); + function = perform_koenig_lookup (function, call_args, false, + tf_none); if (TREE_CODE (function) == IDENTIFIER_NODE - && !processing_template_decl) + && !any_type_dependent_arguments_p (call_args)) { - unqualified_name_lookup_error (function); - release_tree_vector (call_args); - return error_mark_node; + if (koenig_p && (complain & tf_warning_or_error)) + { + /* For backwards compatibility and good diagnostics, try + the unqualified lookup again if we aren't in SFINAE + context. */ + tree unq = (tsubst_copy_and_build + (function, args, complain, in_decl, true, + integral_constant_expression_p)); + if (unq != function) + { + tree fn = unq; + if (TREE_CODE (fn) == COMPONENT_REF) + fn = TREE_OPERAND (fn, 1); + if (is_overloaded_fn (fn)) + fn = get_first_fn (fn); + permerror (EXPR_LOC_OR_HERE (t), + "%qD was not declared in this scope, " + "and no declarations were found by " + "argument-dependent lookup at the point " + "of instantiation", function); + if (DECL_CLASS_SCOPE_P (fn)) + { + inform (EXPR_LOC_OR_HERE (t), + "declarations in dependent base %qT are " + "not found by unqualified lookup", + DECL_CLASS_CONTEXT (fn)); + if (current_class_ptr) + inform (EXPR_LOC_OR_HERE (t), + "use %<this->%D%> instead", function); + else + inform (EXPR_LOC_OR_HERE (t), + "use %<%T::%D%> instead", + TYPE_IDENTIFIER (current_class_type), + function); + } + else + inform (0, "%q+D declared here, later in the " + "translation unit", fn); + function = unq; + } + } + if (TREE_CODE (function) == IDENTIFIER_NODE) + { + unqualified_name_lookup_error (function); + release_tree_vector (call_args); + return error_mark_node; + } } /* Remember that there was a reference to this entity. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 02e08e3..a7ca50d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1953,7 +1953,8 @@ empty_expr_stmt_p (tree expr_stmt) Returns the functions to be considered by overload resolution. */ tree -perform_koenig_lookup (tree fn, VEC(tree,gc) *args, bool include_std) +perform_koenig_lookup (tree fn, VEC(tree,gc) *args, bool include_std, + tsubst_flags_t complain) { tree identifier = NULL_TREE; tree functions = NULL_TREE; @@ -1991,8 +1992,13 @@ perform_koenig_lookup (tree fn, VEC(tree,gc) *args, bool include_std) { fn = lookup_arg_dependent (identifier, functions, args, include_std); if (!fn) - /* The unqualified name could not be resolved. */ - fn = unqualified_fn_lookup_error (identifier); + { + /* The unqualified name could not be resolved. */ + if (complain) + fn = unqualified_fn_lookup_error (identifier); + else + fn = identifier; + } } if (fn && template_id) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2bdb809..ba56b6d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2011-05-20 Jason Merrill <jason@redhat.com> + + * g++.dg/template/koenig9.C: New. + * g++.dg/opt/pr47615.C: Fix. + * g++.dg/overload/defarg1.C: Fix. + * g++.dg/tc1/dr213.C: Remove xfail. + * g++.dg/torture/pr34850.C: Fix. + * g++.dg/torture/pr39362.C: Fix. + * g++.old-deja/g++.brendan/crash56.C: Fix. + * g++.old-deja/g++.pt/memtemp47.C: Fix. + 2011-05-20 Richard Guenther <rguenther@suse.de> PR tree-optimization/49079 diff --git a/gcc/testsuite/g++.dg/opt/pr47615.C b/gcc/testsuite/g++.dg/opt/pr47615.C index bbbcbe1..f8dbcf7 100644 --- a/gcc/testsuite/g++.dg/opt/pr47615.C +++ b/gcc/testsuite/g++.dg/opt/pr47615.C @@ -360,7 +360,7 @@ template < typename Const_Node_Iterator, typename Node_Iterator, typename, typen { { { - rotate_right (p_nd); + this->rotate_right (p_nd); } } } diff --git a/gcc/testsuite/g++.dg/overload/defarg1.C b/gcc/testsuite/g++.dg/overload/defarg1.C index 44de733..5d34a45 100644 --- a/gcc/testsuite/g++.dg/overload/defarg1.C +++ b/gcc/testsuite/g++.dg/overload/defarg1.C @@ -3,7 +3,9 @@ template<typename T> int foo (T t, int = foo(T())); +struct A { }; + int main() { - foo(0); // { dg-error "default argument" } + foo(A()); // { dg-error "default argument" } } diff --git a/gcc/testsuite/g++.dg/tc1/dr213.C b/gcc/testsuite/g++.dg/tc1/dr213.C index 2cc7013..b616ff9 100644 --- a/gcc/testsuite/g++.dg/tc1/dr213.C +++ b/gcc/testsuite/g++.dg/tc1/dr213.C @@ -8,7 +8,7 @@ template <class T> struct A : T { void h(T t) { f(t); - g(t); // { dg-error "" "" { xfail *-*-* } } + g(t); // { dg-message "" } } }; @@ -21,7 +21,7 @@ void f(B) {} int main() { - A<B> ab; // { dg-error "" "" { xfail *-*-* } } + A<B> ab; B b; - ab.h(b); + ab.h(b); // { dg-message "instantiated" } } diff --git a/gcc/testsuite/g++.dg/template/koenig9.C b/gcc/testsuite/g++.dg/template/koenig9.C new file mode 100644 index 0000000..ae74a47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig9.C @@ -0,0 +1,33 @@ +// PR c++/29131 +// int has no associated namespaces, so arg-dep lookup doesn't find g(int). + +template <class T> int f() { return g(T()); } // { dg-error "argument-dependent" } +int g(int); // { dg-message "declared here" } +int i = f<int>(); + +// PR c++/24163 +// Unqualified lookup doesn't find names from dependent bases. + +template <class T> +struct A +{ + static void h(T); +}; + +template <class T> struct B: A<T> +{ + void f() { h(T()); } // { dg-error "argument-dependent" } + static void g() { h(T()); } // { dg-error "argument-dependent" } +}; + +int main() +{ + B<int> b; + b.f(); + b.g(); +} + +// { dg-message "dependent base .A.int" "" { target *-*-* } 19 } +// { dg-message "this->h" "" { target *-*-* } 19 } +// { dg-message "dependent base .A.int" "" { target *-*-* } 20 } +// { dg-message "B::h" "" { target *-*-* } 20 } diff --git a/gcc/testsuite/g++.dg/torture/pr34850.C b/gcc/testsuite/g++.dg/torture/pr34850.C index 4f630f8..5e30f1d 100644 --- a/gcc/testsuite/g++.dg/torture/pr34850.C +++ b/gcc/testsuite/g++.dg/torture/pr34850.C @@ -48,7 +48,7 @@ template<typename T> void MemoryRegion<T>::create(u32bit n) { template<typename T> class SecureVector : public MemoryRegion<T> { public: SecureVector<T>& operator=(const MemoryRegion<T>& in) { - if(this != &in) set(in); + if(this != &in) this->set(in); } }; class OctetString { diff --git a/gcc/testsuite/g++.dg/torture/pr39362.C b/gcc/testsuite/g++.dg/torture/pr39362.C index fb23439..e7b0774 100644 --- a/gcc/testsuite/g++.dg/torture/pr39362.C +++ b/gcc/testsuite/g++.dg/torture/pr39362.C @@ -55,7 +55,7 @@ template <typename T, int cap> class I; template <typename T> struct I <T, 0> : H <T> { I (int capacity) { allocateBuffer (capacity); } - ~I () { deallocateBuffer (buffer ()); } + ~I () { this->deallocateBuffer (buffer ()); } using H <T>::allocateBuffer; H <T>::buffer; }; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C index ad652cf..a22615d 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C @@ -253,7 +253,7 @@ void SetLD<T>::add(const T& item) { if ( ! contains(item) ) - append(item); + this->append(item); } template<class T> void diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C index 7ed5a24..242a299 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C @@ -18,7 +18,7 @@ struct T : public S<X> { template <class U> void f(U u) - { printf ("In T::f(U)\n"); g(u); } + { printf ("In T::f(U)\n"); this->g(u); } }; int main() |