aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/decl.c12
-rw-r--r--gcc/cp/name-lookup.c28
-rw-r--r--gcc/cp/pt.c24
5 files changed, 36 insertions, 47 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1e5fffe..dce229c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2220,11 +2220,6 @@ add_function_candidate (struct z_candidate **candidates,
int viable = 1;
struct rejection_reason *reason = NULL;
- /* At this point we should not see any functions which haven't been
- explicitly declared, except for friend functions which will have
- been found using argument dependent lookup. */
- gcc_assert (!DECL_ANTICIPATED (fn) || DECL_HIDDEN_FRIEND_P (fn));
-
/* The `this', `in_chrg' and VTT arguments to constructors are not
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
@@ -6344,11 +6339,6 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
tree call = extract_call_expr (result);
CALL_EXPR_OPERATOR_SYNTAX (call) = true;
- if (processing_template_decl && DECL_HIDDEN_FRIEND_P (cand->fn))
- /* This prevents build_new_function_call from discarding this
- function during instantiation of the enclosing template. */
- KOENIG_LOOKUP_P (call) = 1;
-
/* Specify evaluation order as per P0145R2. */
CALL_EXPR_ORDERED_ARGS (call) = false;
switch (op_is_ordered (code))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 42d0d76..48a4074 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2720,14 +2720,13 @@ struct GTY(()) lang_decl_fn {
unsigned thunk_p : 1;
unsigned this_thunk_p : 1;
- unsigned hidden_friend_p : 1;
unsigned omp_declare_reduction_p : 1;
unsigned has_dependent_explicit_spec_p : 1;
unsigned immediate_fn_p : 1;
unsigned maybe_deleted : 1;
unsigned coroutine_p : 1;
- unsigned spare : 9;
+ unsigned spare : 10;
/* 32-bits padding on 64-bit host. */
@@ -4067,12 +4066,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define DECL_OMP_PRIVATIZED_MEMBER(NODE) \
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.anticipated_p)
-/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
- within a class but has not been declared in the surrounding scope.
- The function is invisible except via argument dependent lookup. */
-#define DECL_HIDDEN_FRIEND_P(NODE) \
- (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
-
/* Nonzero if NODE is an artificial FUNCTION_DECL for
#pragma omp declare reduction. */
#define DECL_OMP_DECLARE_REDUCTION_P(NODE) \
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 617b96e..14742c1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2141,10 +2141,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
olddecl_hidden_friend = olddecl_friend && was_hidden;
hidden_friend = olddecl_hidden_friend && hiding;
if (!hidden_friend)
- {
- DECL_ANTICIPATED (olddecl) = 0;
- DECL_HIDDEN_FRIEND_P (olddecl) = 0;
- }
+ DECL_ANTICIPATED (olddecl) = false;
}
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -2892,12 +2889,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
DECL_UID (olddecl) = olddecl_uid;
if (olddecl_friend)
- DECL_FRIEND_P (olddecl) = 1;
+ DECL_FRIEND_P (olddecl) = true;
if (hidden_friend)
- {
- DECL_ANTICIPATED (olddecl) = 1;
- DECL_HIDDEN_FRIEND_P (olddecl) = 1;
- }
+ DECL_ANTICIPATED (olddecl) = true;
/* NEWDECL contains the merged attribute lists.
Update OLDDECL to be the same. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index bc60d343..8cd6fe3 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3172,7 +3172,7 @@ do_pushdecl (tree decl, bool hiding)
return error_mark_node;
}
/* Hide it from ordinary lookup. */
- DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true;
+ DECL_ANTICIPATED (decl) = true;
}
}
@@ -4924,8 +4924,15 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
/* Since decl is a function, old should contain a function decl. */
if (!OVL_P (old))
- goto not_found;
+ {
+ not_found:
+ /* It didn't work, go back to the explicit scope. */
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ error ("%qD should have been declared inside %qD", decl, scope);
+ return;
+ }
+
/* We handle these in check_explicit_instantiation_namespace. */
if (processing_explicit_instantiation)
return;
@@ -4935,13 +4942,14 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
match. But, we'll check later, when we construct the
template. */
return;
+
/* Instantiations or specializations of templates may be declared as
friends in any namespace. */
if (friendp && DECL_USE_TEMPLATE (decl))
return;
- tree found;
- found = NULL_TREE;
+ tree found = NULL_TREE;
+ bool hidden_p = false;
for (lkp_iterator iter (old); iter; ++iter)
{
@@ -4957,17 +4965,20 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
{
if (found)
{
- /* We found more than one matching declaration. */
+ /* We found more than one matching declaration. This
+ can happen if we have two inline namespace children,
+ each containing a suitable declaration. */
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
goto ambiguous;
}
found = ofn;
+ hidden_p = iter.hidden_p ();
}
}
if (found)
{
- if (DECL_HIDDEN_FRIEND_P (found))
+ if (hidden_p)
{
pedwarn (DECL_SOURCE_LOCATION (decl), 0,
"%qD has not been declared within %qD", decl, scope);
@@ -4978,10 +4989,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
goto found;
}
- not_found:
- /* It didn't work, go back to the explicit scope. */
- DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- error ("%qD should have been declared inside %qD", decl, scope);
+ goto not_found;
}
/* Return the namespace where the current declaration is declared. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a096337..652b458 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2988,6 +2988,7 @@ check_explicit_specialization (tree declarator,
tree tmpl = NULL_TREE;
tree targs = NULL_TREE;
bool was_template_id = (TREE_CODE (declarator) == TEMPLATE_ID_EXPR);
+ bool found_hidden = false;
/* Make sure that the declarator is a TEMPLATE_ID_EXPR. */
if (!was_template_id)
@@ -3008,12 +3009,15 @@ check_explicit_specialization (tree declarator,
fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
LOOK_want::NORMAL, true);
if (fns == error_mark_node)
- /* If lookup fails, look for a friend declaration so we can
- give a better diagnostic. */
- fns = (lookup_qualified_name
- (CP_DECL_CONTEXT (decl), dname,
- LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND,
- /*complain*/true));
+ {
+ /* If lookup fails, look for a friend declaration so we can
+ give a better diagnostic. */
+ fns = (lookup_qualified_name
+ (CP_DECL_CONTEXT (decl), dname,
+ LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND,
+ /*complain*/true));
+ found_hidden = true;
+ }
if (fns == error_mark_node || !is_overloaded_fn (fns))
{
@@ -3122,8 +3126,7 @@ check_explicit_specialization (tree declarator,
return error_mark_node;
else
{
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_HIDDEN_FRIEND_P (tmpl))
+ if (found_hidden && TREE_CODE (decl) == FUNCTION_DECL)
{
auto_diagnostic_group d;
if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
@@ -3132,8 +3135,9 @@ check_explicit_specialization (tree declarator,
inform (DECL_SOURCE_LOCATION (tmpl),
"friend declaration here");
}
- else if (!ctype && !is_friend
- && CP_DECL_CONTEXT (decl) == current_namespace)
+
+ if (!ctype && !is_friend
+ && CP_DECL_CONTEXT (decl) == current_namespace)
check_unqualified_spec_or_inst (tmpl, DECL_SOURCE_LOCATION (decl));
tree gen_tmpl = most_general_template (tmpl);