aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-01-23 11:35:31 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-01-23 11:35:31 -0500
commitaef3a6b297352e3ac17d7588682dbc956861bf58 (patch)
tree7d70f52991e33cb3ff8fc4c0f1dad261445bf079 /gcc/cp
parent5965b617aa6ad71890de872bdbaa6fd0d7aab216 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/semantics.c15
-rw-r--r--gcc/cp/tree.c18
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. */