diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 15 | ||||
-rw-r--r-- | gcc/cp/tree.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/template-id-2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using20.C | 18 |
10 files changed, 65 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 94e6dc9..b6bf88f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2012-01-23 Jason Merrill <jason@redhat.com> + + PR c++/51925 + * class.c (add_method): Set OVL_USED for using-decls. + * tree.c (ovl_scope): New. + * cp-tree.h: Declare it. + * parser.c (cp_parser_template_name): Use it. + * semantics.c (baselink_for_fns): Likewise. + * name-lookup.c (set_inherited_value_binding_p): Likewise. + 2012-01-20 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51402 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e6f33fe..d654b76 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1118,6 +1118,8 @@ add_method (tree type, tree method, tree using_decl) /* Add the new binding. */ overload = build_overload (method, current_fns); + if (using_decl && TREE_CODE (overload) == OVERLOAD) + OVL_USED (overload) = true; if (conv_p) TYPE_HAS_CONVERSION (type) = 1; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ccad644..f27755e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -75,6 +75,7 @@ c-common.h, not after. IMPLICIT_CONV_EXPR_DIRECT_INIT (in IMPLICIT_CONV_EXPR) TRANSACTION_EXPR_IS_STMT (in TRANSACTION_EXPR) CONVERT_EXPR_VBASE_PATH (in CONVERT_EXPR) + OVL_ARG_DEPENDENT (in OVERLOAD) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -5679,6 +5680,7 @@ extern tree get_fns (tree); extern tree get_first_fn (tree); extern tree ovl_cons (tree, tree); extern tree build_overload (tree, tree); +extern tree ovl_scope (tree); extern bool non_static_member_function_p (tree); extern const char *cxx_printable_name (tree, int); extern const char *cxx_printable_name_translate (tree, int); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 5734055..2351342 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2853,7 +2853,7 @@ set_inherited_value_binding_p (cxx_binding *binding, tree decl, tree context; if (TREE_CODE (decl) == OVERLOAD) - context = CP_DECL_CONTEXT (OVL_CURRENT (decl)); + context = ovl_scope (decl); else { gcc_assert (DECL_P (decl)); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c4c3ef4..491f48e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12722,7 +12722,7 @@ cp_parser_template_name (cp_parser* parser, its name; we will look it up again during template instantiation. */ if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl)) { - tree scope = CP_DECL_CONTEXT (get_first_fn (decl)); + tree scope = ovl_scope (decl); if (TYPE_P (scope) && dependent_type_p (scope)) return identifier; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a5a10d0..9019962 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2807,23 +2807,20 @@ finish_base_specifier (tree base, tree access, bool virtual_p) tree baselink_for_fns (tree fns) { - tree fn; + tree scope; tree cl; if (BASELINK_P (fns) || error_operand_p (fns)) return fns; - - fn = fns; - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = TREE_OPERAND (fn, 0); - fn = get_first_fn (fn); - if (!DECL_FUNCTION_MEMBER_P (fn)) + + scope = ovl_scope (fns); + if (!CLASS_TYPE_P (scope)) return fns; - cl = currently_open_derived_class (DECL_CONTEXT (fn)); + cl = currently_open_derived_class (scope); if (!cl) - cl = DECL_CONTEXT (fn); + cl = scope; cl = TYPE_BINFO (cl); return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index bf8bc05..cf39800 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1525,6 +1525,24 @@ build_overload (tree decl, tree chain) return ovl_cons (decl, chain); } +/* Return the scope where the overloaded functions OVL were found. */ + +tree +ovl_scope (tree ovl) +{ + if (TREE_CODE (ovl) == OFFSET_REF + || TREE_CODE (ovl) == COMPONENT_REF) + ovl = TREE_OPERAND (ovl, 1); + if (TREE_CODE (ovl) == BASELINK) + return BINFO_TYPE (BASELINK_BINFO (ovl)); + if (TREE_CODE (ovl) == TEMPLATE_ID_EXPR) + ovl = TREE_OPERAND (ovl, 0); + /* Skip using-declarations. */ + while (TREE_CODE (ovl) == OVERLOAD && OVL_USED (ovl) && OVL_CHAIN (ovl)) + ovl = OVL_CHAIN (ovl); + return CP_DECL_CONTEXT (OVL_CURRENT (ovl)); +} + /* Return TRUE if FN is a non-static member function, FALSE otherwise. This function looks into BASELINK and OVERLOAD nodes. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 57c6060..6ba32c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-01-22 Jason Merrill <jason@redhat.com> + + PR c++/51925 + * g++.dg/template/using20.C: New. + * g++.dg/template/template-id-2.C: Adjust diagnostic. + 2012-01-23 Jason Merrill <jason@redhat.com> PR target/51934 diff --git a/gcc/testsuite/g++.dg/template/template-id-2.C b/gcc/testsuite/g++.dg/template/template-id-2.C index 333e33d..d214716 100644 --- a/gcc/testsuite/g++.dg/template/template-id-2.C +++ b/gcc/testsuite/g++.dg/template/template-id-2.C @@ -11,7 +11,7 @@ template<> struct A<void> template<typename T> void foo() { A<T> a; - a.template foo<int>(); // { dg-error "no member" } + a.template foo<int>(); // { dg-error "member" } } }; diff --git a/gcc/testsuite/g++.dg/template/using20.C b/gcc/testsuite/g++.dg/template/using20.C new file mode 100644 index 0000000..1df9549 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using20.C @@ -0,0 +1,18 @@ +// PR c++/51925 + +struct E +{ + int e (); +}; +template <typename T1> +struct G : public E +{ + using E::e; + template <int> void e (); + void f () { e <0> (); } +}; +int f(void) +{ + G<int> a; + a.f(); +} |