c++: DECL_BUILTIN_P for builtins
authorNathan Sidwell <nathan@acm.org>
Fri, 25 Sep 2020 13:53:06 +0000 (06:53 -0700)
committerNathan Sidwell <nathan@acm.org>
Fri, 25 Sep 2020 13:58:07 +0000 (06:58 -0700)
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.

gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
libcc1/libcp1plugin.cc

index 3ae48749b3ded42b39cfe174632fba25a40610ae..bd78f00ba9799195b97f018f3b8454c70e84d9b0 100644 (file)
@@ -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
index 6019051ed12a334b71a45ceeb152d819ec64efb8..1709dd9a370bb0fcdbfe91f6db657547590dd013 100644 (file)
@@ -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)
index e7764abff67997d02cc70f2add192d9da5ada4c6..dbc6cc32dd8a9cfcc4128faed22732845f9d05a6 100644 (file)
@@ -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.  */
index fba3fcc0c4c44bfd7b75a3f995f35a48358ecffe..ccfae78f65118745263bc5fcde386ebc63e11837 100644 (file)
@@ -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);
index 6f8dbc3bc7464658d1fec190db1868f8b2d03f19..a4530dba14e1f2f665f51d265caa3254112d9f6b 100644 (file)
@@ -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);
                  }
index 279bb8423934fb03502463dc73e7441f6e5e5a39..3fe310dbb8e93c02af1697257e877d115b9260fb 100644 (file)
@@ -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)