diff options
author | Jason Merrill <jason@redhat.com> | 2012-01-23 11:35:31 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-01-23 11:35:31 -0500 |
commit | aef3a6b297352e3ac17d7588682dbc956861bf58 (patch) | |
tree | 7d70f52991e33cb3ff8fc4c0f1dad261445bf079 /gcc/cp | |
parent | 5965b617aa6ad71890de872bdbaa6fd0d7aab216 (diff) | |
download | gcc-aef3a6b297352e3ac17d7588682dbc956861bf58.zip gcc-aef3a6b297352e3ac17d7588682dbc956861bf58.tar.gz gcc-aef3a6b297352e3ac17d7588682dbc956861bf58.tar.bz2 |
re PR c++/51925 (ICE in tsubst with using and template function)
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.
From-SVN: r183438
Diffstat (limited to 'gcc/cp')
-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 |
7 files changed, 40 insertions, 11 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. */ |