c++: Failure to lookup using-decl name [PR98231]
In r11-4690 we removed the call to finish_nonmember_using_decl in tsubst_expr/DECL_EXPR in the USING_DECL block. This was done not to perform name lookup twice for a non-dependent using-decl, which sounds sensible. However, finish_nonmember_using_decl also pushes the decl's bindings which we still have to do so that we can find the USING_DECL's name later. In this case, we've got a USING_DECL N::operator<< that we are tsubstituting. We already looked it up while parsing the template "foo", and lookup_using_decl stashed the OVERLOAD it found into USING_DECL_DECLS. Now we just have to update the IDENTIFIER_BINDING of the identifier for operator<< with the overload the name is bound to. I didn't want to export push_local_binding so I've introduced a new wrapper. gcc/cp/ChangeLog: PR c++/98231 * name-lookup.c (push_using_decl_bindings): New. * name-lookup.h (push_using_decl_bindings): Declare. * pt.c (tsubst_expr): Call push_using_decl_bindings. gcc/testsuite/ChangeLog: PR c++/98231 * g++.dg/lookup/using63.C: New test.
This commit is contained in:
parent
8fc183ccd0
commit
796ead19f8
@ -9279,4 +9279,14 @@ push_operator_bindings ()
|
||||
}
|
||||
}
|
||||
|
||||
/* Wrapper around push_local_binding to push the bindings for
|
||||
a non-member USING_DECL DECL that was found during template parsing. */
|
||||
|
||||
void
|
||||
push_using_decl_bindings (tree decl)
|
||||
{
|
||||
push_local_binding (DECL_NAME (decl), USING_DECL_DECLS (decl),
|
||||
/*using*/true);
|
||||
}
|
||||
|
||||
#include "gt-cp-name-lookup.h"
|
||||
|
@ -478,6 +478,7 @@ extern void push_to_top_level (void);
|
||||
extern void pop_from_top_level (void);
|
||||
extern void maybe_save_operator_binding (tree);
|
||||
extern void push_operator_bindings (void);
|
||||
extern void push_using_decl_bindings (tree);
|
||||
extern void discard_operator_bindings (tree);
|
||||
|
||||
/* Lower level interface for modules. */
|
||||
|
@ -18133,6 +18133,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
|
||||
tree scope = USING_DECL_SCOPE (decl);
|
||||
gcc_checking_assert (scope
|
||||
== tsubst (scope, args, complain, in_decl));
|
||||
/* We still need to push the bindings so that we can look up
|
||||
this name later. */
|
||||
push_using_decl_bindings (decl);
|
||||
}
|
||||
else if (is_capture_proxy (decl)
|
||||
&& !DECL_TEMPLATE_INSTANTIATION (current_function_decl))
|
||||
|
17
gcc/testsuite/g++.dg/lookup/using63.C
Normal file
17
gcc/testsuite/g++.dg/lookup/using63.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/98231
|
||||
// { dg-do compile }
|
||||
|
||||
template <typename, typename = int> struct basic_ostream {};
|
||||
namespace N {
|
||||
template <typename Char, typename CharTraits, typename T>
|
||||
void operator<<(basic_ostream<Char, CharTraits>, T);
|
||||
}
|
||||
basic_ostream<char> os;
|
||||
|
||||
template<typename T> void
|
||||
foo (T value)
|
||||
{
|
||||
using N::operator<<;
|
||||
os << value;
|
||||
}
|
||||
void bar() { foo (1); }
|
Loading…
Reference in New Issue
Block a user