Commit b01e6d2b by Jason Merrill

re PR c++/26102 ("using Base::member" nonsense)

        PR c++/26102
        * name-lookup.c (do_class_using_decl): Try to find the base even
        if bases_dependent_p.
        * pt.c (type_dependent_expression_p): A USING_DECL is dependent.

        PR c++/19809
        * pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl.

From-SVN: r116709
parent 6dd0d2f4
......@@ -2824,18 +2824,19 @@ do_class_using_decl (tree scope, tree name)
class type. However, if all of the base classes are
non-dependent, then we can avoid delaying the check until
instantiation. */
if (!scope_dependent_p && !bases_dependent_p)
if (!scope_dependent_p)
{
base_kind b_kind;
tree binfo;
binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
if (b_kind < bk_proper_base)
{
error_not_base_type (scope, current_class_type);
return NULL_TREE;
if (!bases_dependent_p)
{
error_not_base_type (scope, current_class_type);
return NULL_TREE;
}
}
if (!name_dependent_p)
else if (!name_dependent_p)
{
decl = lookup_member (binfo, name, 0, false);
if (!decl)
......
......@@ -5333,6 +5333,10 @@ tsubst_friend_function (tree decl, tree args)
else
new_friend_result_template_info = NULL_TREE;
/* Make the init_value nonzero so pushdecl knows this is a defn. */
if (new_friend_is_defn)
DECL_INITIAL (new_friend) = error_mark_node;
/* Inside pushdecl_namespace_level, we will push into the
current namespace. However, the friend function should go
into the namespace of the template. */
......@@ -12862,7 +12866,8 @@ type_dependent_expression_p (tree expression)
return false;
/* An unresolved name is always dependent. */
if (TREE_CODE (expression) == IDENTIFIER_NODE)
if (TREE_CODE (expression) == IDENTIFIER_NODE
|| TREE_CODE (expression) == USING_DECL)
return true;
/* Some expression forms are never type-dependent. */
......
// PR c++/19809
template<int i>
struct n{
friend void foo(){ } // { dg-error "defin" }
};
int main(){
n<1> n1;
n<2> n2;
}
// PR c++/26102
template <class T> struct B1 { int i(); };
struct B2 { int i(); };
template <class T> struct C : public B1<T>, public B2
{
using B2::i;
void f()
{
i(); // should be accepted
i.i(); // { dg-error "" }
}
};
int main()
{
C<int> c;
c.f(); // { dg-error "instantiated" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment