aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/template-id-2.C2
-rw-r--r--gcc/testsuite/g++.dg/template/using20.C18
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();
+}