aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-05-20 14:01:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-05-20 14:01:22 -0400
commit94df301fa033641561145d44ed48cf4c85d43a2c (patch)
treea133483f2142f1c02de48fd4af4865636ad9ed75 /gcc
parent6e04dcd56f7d94288467234f065fca6006761cfe (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/cp/pt.c69
-rw-r--r--gcc/cp/semantics.c12
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/opt/pr47615.C2
-rw-r--r--gcc/testsuite/g++.dg/overload/defarg1.C4
-rw-r--r--gcc/testsuite/g++.dg/tc1/dr213.C6
-rw-r--r--gcc/testsuite/g++.dg/template/koenig9.C33
-rw-r--r--gcc/testsuite/g++.dg/torture/pr34850.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr39362.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash56.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C2
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()