c++: DECL_BUILTIN_P for builtins
We currently detect builtin decls via DECL_ARTIFICIAL && !DECL_HIDDEN_FUNCTION_P, which, besides being clunky, is a problem as hiddenness is a property of the symbol table -- not the decl being hidden. This adds DECL_BUILTIN_P, which just looks at the SOURCE_LOCATION -- we have a magic one for builtins. One of the consequential changes is to make function-scope omp udrs have function context (needed because otherwise duplicate-decls thinks the types don't match at the point we check). This is also morally better, because that's what they are -- nested functions, stop lying. (That's actually my plan for all DECL_LOCAL_DECL_P decls, as they are distinct decls to the namespace-scope decl they alias.) gcc/cp/ * cp-tree.h (DECL_BUILTIN_P): New. * decl.c (duplicate_decls): Use it. Do not treat omp-udr as a builtin. * name-lookup.c (anticipated_builtin): Use it. (set_decl_context_in_fn): Function-scope OMP UDRs have function context. (do_nonmember_using_decl): Use DECL_BUILTIN_P. * parser.c (cp_parser_omp_declare_reduction): Function-scope OMP UDRs have function context. Assert we never find a valid duplicate. * pt.c (tsubst_expr): Function-scope OMP UDRs have function context. libcc1/ * libcp1plugin.cc (supplement_binding): Use DECL_BULTIN_P.
This commit is contained in:
parent
69cf7decf1
commit
a28542df4d
@ -4040,6 +4040,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
||||
#define FNDECL_USED_AUTO(NODE) \
|
||||
TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE))
|
||||
|
||||
/* True if NODE is a builtin decl. */
|
||||
#define DECL_BUILTIN_P(NODE) \
|
||||
(DECL_SOURCE_LOCATION(NODE) == BUILTINS_LOCATION)
|
||||
|
||||
/* Nonzero if NODE is a DECL which we know about but which has not
|
||||
been explicitly declared, such as a built-in function or a friend
|
||||
declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P
|
||||
|
||||
@ -1464,9 +1464,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
||||
|
||||
/* Check for redeclaration and other discrepancies. */
|
||||
if (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& DECL_ARTIFICIAL (olddecl)
|
||||
/* A C++20 implicit friend operator== uses the normal path (94462). */
|
||||
&& !DECL_HIDDEN_FRIEND_P (olddecl))
|
||||
&& DECL_BUILTIN_P (olddecl))
|
||||
{
|
||||
if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
{
|
||||
@ -1508,15 +1506,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
||||
"declaration %q#D", newdecl, olddecl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (DECL_OMP_DECLARE_REDUCTION_P (olddecl))
|
||||
{
|
||||
gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (newdecl));
|
||||
error_at (newdecl_loc,
|
||||
"redeclaration of %<pragma omp declare reduction%>");
|
||||
inform (olddecl_loc,
|
||||
"previous %<pragma omp declare reduction%> declaration");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (!types_match)
|
||||
{
|
||||
/* Avoid warnings redeclaring built-ins which have not been
|
||||
@ -1815,6 +1804,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& DECL_OMP_DECLARE_REDUCTION_P (newdecl))
|
||||
{
|
||||
/* OMP UDRs are never duplicates. */
|
||||
gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (olddecl));
|
||||
error_at (newdecl_loc,
|
||||
"redeclaration of %<pragma omp declare reduction%>");
|
||||
inform (olddecl_loc,
|
||||
"previous %<pragma omp declare reduction%> declaration");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& ((DECL_TEMPLATE_SPECIALIZATION (olddecl)
|
||||
&& (!DECL_TEMPLATE_INFO (newdecl)
|
||||
|
||||
@ -2119,10 +2119,10 @@ anticipated_builtin_p (tree ovl)
|
||||
tree fn = OVL_FUNCTION (ovl);
|
||||
gcc_checking_assert (DECL_ANTICIPATED (fn));
|
||||
|
||||
if (DECL_HIDDEN_FRIEND_P (fn))
|
||||
return false;
|
||||
if (DECL_BUILTIN_P (fn))
|
||||
return true;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* BINDING records an existing declaration for a name in the current scope.
|
||||
@ -2857,9 +2857,12 @@ set_decl_context_in_fn (tree ctx, tree decl)
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (VAR_P (decl) && DECL_EXTERNAL (decl)))
|
||||
/* Make sure local externs are marked as such. */
|
||||
/* Make sure local externs are marked as such. OMP UDRs really
|
||||
are nested functions. */
|
||||
gcc_checking_assert (DECL_LOCAL_DECL_P (decl)
|
||||
&& DECL_NAMESPACE_SCOPE_P (decl));
|
||||
&& (DECL_NAMESPACE_SCOPE_P (decl)
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_OMP_DECLARE_REDUCTION_P (decl))));
|
||||
|
||||
if (!DECL_CONTEXT (decl)
|
||||
/* When parsing the parameter list of a function declarator,
|
||||
@ -3934,7 +3937,7 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
|
||||
}
|
||||
else if (old.using_p ())
|
||||
continue; /* This is a using decl. */
|
||||
else if (old.hidden_p () && !DECL_HIDDEN_FRIEND_P (old_fn))
|
||||
else if (old.hidden_p () && DECL_BUILTIN_P (old_fn))
|
||||
continue; /* This is an anticipated builtin. */
|
||||
else if (!matching_fn_p (new_fn, old_fn))
|
||||
continue; /* Parameters do not match. */
|
||||
|
||||
@ -42567,7 +42567,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
|
||||
if (current_function_decl)
|
||||
{
|
||||
block_scope = true;
|
||||
DECL_CONTEXT (fndecl) = global_namespace;
|
||||
DECL_CONTEXT (fndecl) = current_function_decl;
|
||||
DECL_LOCAL_DECL_P (fndecl) = true;
|
||||
if (!processing_template_decl)
|
||||
pushdecl (fndecl);
|
||||
@ -42592,7 +42592,9 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
|
||||
else
|
||||
{
|
||||
DECL_CONTEXT (fndecl) = current_namespace;
|
||||
pushdecl (fndecl);
|
||||
tree d = pushdecl (fndecl);
|
||||
/* We should never meet a matched duplicate decl. */
|
||||
gcc_checking_assert (d == error_mark_node || d == fndecl);
|
||||
}
|
||||
if (!block_scope)
|
||||
start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
|
||||
|
||||
11
gcc/cp/pt.c
11
gcc/cp/pt.c
@ -18109,16 +18109,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
|
||||
else if (DECL_IMPLICIT_TYPEDEF_P (t))
|
||||
/* We already did a pushtag. */;
|
||||
else if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_OMP_DECLARE_REDUCTION_P (decl)
|
||||
&& DECL_FUNCTION_SCOPE_P (pattern_decl))
|
||||
&& DECL_LOCAL_DECL_P (decl)
|
||||
&& DECL_OMP_DECLARE_REDUCTION_P (decl))
|
||||
{
|
||||
/* We pretend this is regular local extern decl of
|
||||
a namespace-scope fn. Then we make it really
|
||||
local, it is a nested function. */
|
||||
gcc_checking_assert (DECL_LOCAL_DECL_P (decl));
|
||||
DECL_CONTEXT (decl) = global_namespace;
|
||||
pushdecl (decl);
|
||||
DECL_CONTEXT (decl) = current_function_decl;
|
||||
pushdecl (decl);
|
||||
if (cp_check_omp_declare_reduction (decl))
|
||||
instantiate_body (pattern_decl, args, decl, true);
|
||||
}
|
||||
|
||||
@ -354,7 +354,7 @@ supplement_binding (cxx_binding *binding, tree decl)
|
||||
declared, pretend it is not there at all. */
|
||||
|| (TREE_CODE (target_bval) == FUNCTION_DECL
|
||||
&& DECL_ANTICIPATED (target_bval)
|
||||
&& !DECL_HIDDEN_FRIEND_P (target_bval)))
|
||||
&& DECL_BUILTIN_P (target_bval)))
|
||||
binding->value = decl;
|
||||
else if (TREE_CODE (target_bval) == TYPE_DECL
|
||||
&& DECL_ARTIFICIAL (target_bval)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user