summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-15 21:14:05 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-15 21:14:05 +0000
commit521a6373b97d37cab16ffe7e280119dd2d3efa02 (patch)
tree2e45a14353f0c3873d716c8fe004c3189dbf32fa
parentbbf582248a5839237f0c8230371ce87c807bf768 (diff)
downloadgcc-521a6373b97d37cab16ffe7e280119dd2d3efa02.tar.gz
PR c++/69753
* search.c (any_dependent_bases_p): Split out... * name-lookup.c (do_class_using_decl): ...from here. * call.c (build_new_method_call_1): Don't complain about missing object if there are dependent bases. Tweak error. * tree.c (non_static_member_function_p): Remove. * pt.c (type_dependent_expression_p): A member template of a dependent type is dependent. * cp-tree.h: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233431 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c13
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/cp/search.c18
-rw-r--r--gcc/cp/semantics.c23
-rw-r--r--gcc/cp/tree.c17
-rw-r--r--gcc/testsuite/g++.dg/lookup/member3.C17
9 files changed, 64 insertions, 56 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 85473df23d5..04d55bc60b9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,17 @@
2016-02-15 Jason Merrill <jason@redhat.com>
+ PR c++/69753
+ * semantics.c (finish_call_expr): Implicit 'this' does not make
+ the call dependent.
+ * search.c (any_dependent_bases_p): Split out...
+ * name-lookup.c (do_class_using_decl): ...from here.
+ * call.c (build_new_method_call_1): Don't complain about missing object
+ if there are dependent bases. Tweak error.
+ * tree.c (non_static_member_function_p): Remove.
+ * pt.c (type_dependent_expression_p): A member template of a
+ dependent type is dependent.
+ * cp-tree.h: Adjust.
+
PR c++/68890
* constexpr.c (verify_ctor_sanity): Remove CONSTRUCTOR_NELTS check.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cb71176c6ca..db406543522 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8160,7 +8160,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (permerror (input_location,
"cannot call constructor %<%T::%D%> directly",
- basetype, name))
+ BINFO_TYPE (access_binfo), name))
inform (input_location, "for a function-style cast, remove the "
"redundant %<::%D%>", name);
call = build_functional_cast (basetype, build_tree_list_vec (user_args),
@@ -8377,6 +8377,9 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
we know we really need it. */
cand->first_arg = instance;
}
+ else if (any_dependent_bases_p ())
+ /* We can't tell until instantiation time whether we can use
+ *this as the implicit object argument. */;
else
{
if (complain & tf_error)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3b91089f50d..b7d7bc68502 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6252,6 +6252,7 @@ extern tree adjust_result_of_qualified_name_lookup
extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree);
extern int shared_member_p (tree);
+extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ());
/* The representation of a deferred access check. */
@@ -6542,7 +6543,6 @@ 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);
extern tree build_exception_variant (tree, tree);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 8d6e75a1347..b5961e573f3 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3333,8 +3333,6 @@ do_class_using_decl (tree scope, tree name)
/* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */
bool bases_dependent_p;
tree binfo;
- tree base_binfo;
- int i;
if (name == error_mark_node)
return NULL_TREE;
@@ -3371,16 +3369,7 @@ do_class_using_decl (tree scope, tree name)
|| (IDENTIFIER_TYPENAME_P (name)
&& dependent_type_p (TREE_TYPE (name))));
- bases_dependent_p = false;
- if (processing_template_decl)
- for (binfo = TYPE_BINFO (current_class_type), i = 0;
- BINFO_BASE_ITERATE (binfo, i, base_binfo);
- i++)
- if (dependent_type_p (TREE_TYPE (base_binfo)))
- {
- bases_dependent_p = true;
- break;
- }
+ bases_dependent_p = any_dependent_bases_p (current_class_type);
decl = NULL_TREE;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a55dc10fdfc..52e60b948b4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -22904,9 +22904,16 @@ type_dependent_expression_p (tree expression)
&& DECL_TEMPLATE_INFO (expression))
return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
- if (TREE_CODE (expression) == TEMPLATE_DECL
- && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
- return false;
+ if (TREE_CODE (expression) == TEMPLATE_DECL)
+ {
+ if (DECL_CLASS_SCOPE_P (expression)
+ && dependent_type_p (DECL_CONTEXT (expression)))
+ /* A template's own parameters don't make it dependent, since those can
+ be deduced, but the enclosing class does. */
+ return true;
+ if (!DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
+ return false;
+ }
if (TREE_CODE (expression) == STMT_EXPR)
expression = stmt_expr_value_expr (expression);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 79246118915..49f3bc5ed80 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2842,3 +2842,21 @@ original_binfo (tree binfo, tree here)
return result;
}
+/* True iff TYPE has any dependent bases (and therefore we can't say
+ definitively that another class is not a base of an instantiation of
+ TYPE). */
+
+bool
+any_dependent_bases_p (tree type)
+{
+ if (!type || !CLASS_TYPE_P (type) || !processing_template_decl)
+ return false;
+
+ unsigned i;
+ tree base_binfo;
+ FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo)
+ if (BINFO_DEPENDENT_BASE_P (base_binfo))
+ return true;
+
+ return false;
+}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0cf5f930b1e..0f6a6b5c539 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2264,17 +2264,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
with no type; type_dependent_expression_p recognizes
expressions with no type as being dependent. */
if (type_dependent_expression_p (fn)
- || any_type_dependent_arguments_p (*args)
- /* For a non-static member function that doesn't have an
- explicit object argument, we need to specifically
- test the type dependency of the "this" pointer because it
- is not included in *ARGS even though it is considered to
- be part of the list of arguments. Note that this is
- related to CWG issues 515 and 1005. */
- || (TREE_CODE (fn) != COMPONENT_REF
- && non_static_member_function_p (fn)
- && current_class_ref
- && type_dependent_expression_p (current_class_ref)))
+ || any_type_dependent_arguments_p (*args))
{
result = build_nt_call_vec (fn, *args);
SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
@@ -2354,17 +2344,6 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
NULL);
- if (processing_template_decl)
- {
- if (type_dependent_expression_p (object))
- {
- tree ret = build_nt_call_vec (orig_fn, orig_args);
- release_tree_vector (orig_args);
- return ret;
- }
- object = build_non_dependent_expr (object);
- }
-
result = build_new_method_call (object, fn, args, NULL_TREE,
(disallow_virtual
? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 3203acaff9e..041facda96a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2071,23 +2071,6 @@ ovl_scope (tree 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. */
-
-bool
-non_static_member_function_p (tree fn)
-{
- if (fn == NULL_TREE)
- return false;
-
- if (is_overloaded_fn (fn))
- fn = get_first_fn (fn);
-
- return (DECL_P (fn)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn));
-}
-
#define PRINT_RING_SIZE 4
diff --git a/gcc/testsuite/g++.dg/lookup/member3.C b/gcc/testsuite/g++.dg/lookup/member3.C
new file mode 100644
index 00000000000..f4e097e4719
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/member3.C
@@ -0,0 +1,17 @@
+// PR c++/69753
+// { dg-do compile { target c++11 } }
+
+class A {
+public:
+ template <typename> void As();
+ static A *FromWebContents();
+ A *FromWebContents2();
+};
+template <typename T> class B : A {
+ void FromWebContents() {
+ auto guest = A::FromWebContents();
+ guest ? guest->As<T>() : nullptr;
+ auto guest2 = A::FromWebContents2();
+ guest2 ? guest2->As<T>() : nullptr;
+ }
+};