aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/search.c20
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/this2.C8
-rw-r--r--gcc/testsuite/g++.dg/template/pr97399.C23
6 files changed, 47 insertions, 14 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 51139f4..3046c83 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7312,7 +7312,7 @@ extern tree adjust_result_of_qualified_name_lookup
(tree, tree, tree);
extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree);
-extern int shared_member_p (tree);
+extern bool shared_member_p (tree);
extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ());
extern bool maybe_check_overriding_exception_spec (tree, tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e0208d0..e196db1 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -21413,6 +21413,7 @@ cp_parser_init_declarator (cp_parser* parser,
bool is_non_constant_init;
int ctor_dtor_or_conv_p;
bool friend_p = cp_parser_friend_p (decl_specifiers);
+ bool static_p = decl_specifiers->storage_class == sc_static;
tree pushed_scope = NULL_TREE;
bool range_for_decl_p = false;
bool saved_default_arg_ok_p = parser->default_arg_ok_p;
@@ -21446,7 +21447,7 @@ cp_parser_init_declarator (cp_parser* parser,
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
flags, &ctor_dtor_or_conv_p,
/*parenthesized_p=*/NULL,
- member_p, friend_p, /*static_p=*/false);
+ member_p, friend_p, static_p);
/* Gather up the deferred checks. */
stop_deferring_access_checks ();
@@ -22122,7 +22123,7 @@ cp_parser_direct_declarator (cp_parser* parser,
tree save_ccp = current_class_ptr;
tree save_ccr = current_class_ref;
- if (memfn)
+ if (memfn && !friend_p)
/* DR 1207: 'this' is in scope after the cv-quals. */
inject_this_parameter (current_class_type, cv_quals);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index dd3773d..81bdd45 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -910,7 +910,7 @@ struct lookup_field_info {
const char *errstr;
};
-/* Nonzero for a class member means that it is shared between all objects
+/* True for a class member means that it is shared between all objects
of that class.
[class.member.lookup]:If the resulting set of declarations are not all
@@ -920,25 +920,27 @@ struct lookup_field_info {
This function checks that T contains no non-static members. */
-int
+bool
shared_member_p (tree t)
{
- if (VAR_P (t) || TREE_CODE (t) == TYPE_DECL \
+ if (VAR_P (t) || TREE_CODE (t) == TYPE_DECL
|| TREE_CODE (t) == CONST_DECL)
- return 1;
+ return true;
if (is_overloaded_fn (t))
{
for (ovl_iterator iter (get_fns (t)); iter; ++iter)
{
tree decl = strip_using_decl (*iter);
- /* We don't expect or support dependent decls. */
- gcc_assert (TREE_CODE (decl) != USING_DECL);
+ if (TREE_CODE (decl) == USING_DECL)
+ /* Conservatively assume a dependent using-declaration
+ might resolve to a non-static member. */
+ return false;
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* Routine to see if the sub-object denoted by the binfo PARENT can be
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0670952..51841dc 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2214,8 +2214,7 @@ finish_qualified_id_expr (tree qualifying_class,
{
/* See if any of the functions are non-static members. */
/* If so, the expression may be relative to 'this'. */
- if ((type_dependent_expression_p (expr)
- || !shared_member_p (expr))
+ if (!shared_member_p (expr)
&& current_class_ptr
&& DERIVED_FROM_P (qualifying_class,
current_nonlambda_class_type ()))
diff --git a/gcc/testsuite/g++.dg/cpp0x/this2.C b/gcc/testsuite/g++.dg/cpp0x/this2.C
new file mode 100644
index 0000000..ccc2608
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/this2.C
@@ -0,0 +1,8 @@
+// PR c++/88548
+// { dg-do compile { target c++11 } }
+
+struct S {
+ int a;
+ template <class> static auto m1 ()
+ -> decltype(this->a) { return 0; } // { dg-error "'this'" }
+};
diff --git a/gcc/testsuite/g++.dg/template/pr97399.C b/gcc/testsuite/g++.dg/template/pr97399.C
new file mode 100644
index 0000000..4bb8189
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr97399.C
@@ -0,0 +1,23 @@
+// PR c++/97399
+// { dg-do compile { target c++11 } }
+
+template <bool> struct enable_if_t {};
+
+struct tmp {
+ template <class> static constexpr bool is_integral();
+ template <class T> static auto f()
+ -> enable_if_t<tmp::is_integral<T>()>;
+ template <class T> friend auto g(tmp, T)
+ -> enable_if_t<!tmp::is_integral<T>()>;
+};
+
+template <class> constexpr bool tmp::is_integral() { return true; }
+
+template <class T> auto tmp::f()
+ -> enable_if_t<tmp::is_integral<T>()> { return {}; }
+
+int main()
+{
+ tmp::f<int>();
+ g(tmp{}, 0);
+}