]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/attribs.c
[Ada] Remove Determine_License
[thirdparty/gcc.git] / gcc / attribs.c
index f4777c6a823364fc37b6f2cdc922f1b6e3e8334b..71dae123af841303d6f3c3f2ad5ca68a1eefc9ca 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions dealing with attribute handling, used by most front ends.
-   Copyright (C) 1992-2019 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -573,31 +573,26 @@ decl_attributes (tree *node, tree attributes, int flags,
            }
          continue;
        }
-      else if (list_length (args) < spec->min_length
-              || (spec->max_length >= 0
-                  && list_length (args) > spec->max_length))
+      else
        {
-         error ("wrong number of arguments specified for %qE attribute",
-                name);
-         continue;
+         int nargs = list_length (args);
+         if (nargs < spec->min_length
+             || (spec->max_length >= 0
+                 && nargs > spec->max_length))
+           {
+             error ("wrong number of arguments specified for %qE attribute",
+                    name);
+             if (spec->max_length < 0)
+               inform (input_location, "expected %i or more, found %i",
+                       spec->min_length, nargs);
+             else
+               inform (input_location, "expected between %i and %i, found %i",
+                       spec->min_length, spec->max_length, nargs);
+             continue;
+           }
        }
       gcc_assert (is_attribute_p (spec->name, name));
 
-      if (TYPE_P (*node)
-         && cxx11_attr_p
-         && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
-       {
-         /* This is a c++11 attribute that appertains to a
-            type-specifier, outside of the definition of, a class
-            type.  Ignore it.  */
-         auto_diagnostic_group d;
-         if (warning (OPT_Wattributes, "attribute ignored"))
-           inform (input_location,
-                   "an attribute that appertains to a type-specifier "
-                   "is ignored");
-         continue;
-       }
-
       if (spec->decl_required && !DECL_P (*anode))
        {
          if (flags & ((int) ATTR_FLAG_DECL_NEXT
@@ -682,7 +677,8 @@ decl_attributes (tree *node, tree attributes, int flags,
         reject incompatible attributes.  */
       bool built_in = flags & ATTR_FLAG_BUILT_IN;
       if (spec->exclude
-         && (flag_checking || !built_in))
+         && (flag_checking || !built_in)
+         && !error_operand_p (last_decl))
        {
          /* Always check attributes on user-defined functions.
             Check them on built-ins only when -fchecking is set.
@@ -691,6 +687,7 @@ decl_attributes (tree *node, tree attributes, int flags,
 
          if (!built_in
              || !DECL_P (*anode)
+             || DECL_BUILT_IN_CLASS (*anode) != BUILT_IN_NORMAL
              || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
                  && (DECL_FUNCTION_CODE (*anode)
                      != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
@@ -2020,6 +2017,65 @@ maybe_diag_alias_attributes (tree alias, tree target)
     }
 }
 
+/* Initialize a mapping for a call to function FNDECL declared with
+   attribute access.  Each attribute positional operand inserts one
+   entry into the mapping with the operand number as the key.  */
+
+void
+init_attr_rdwr_indices (rdwr_map *rwm, tree fntype)
+{
+  if (!fntype)
+    return;
+
+  for (tree access = TYPE_ATTRIBUTES (fntype);
+       (access = lookup_attribute ("access", access));
+       access = TREE_CHAIN (access))
+    {
+      /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE
+        is the attribute argument's value.  */
+      tree mode = TREE_VALUE (access);
+      gcc_assert (TREE_CODE (mode) == TREE_LIST);
+      mode = TREE_VALUE (mode);
+      gcc_assert (TREE_CODE (mode) == STRING_CST);
+
+      const char *modestr = TREE_STRING_POINTER (mode);
+      for (const char *m = modestr; *m; )
+       {
+         attr_access acc = { };
+
+         switch (*m)
+           {
+           case 'r': acc.mode = acc.read_only; break;
+           case 'w': acc.mode = acc.write_only; break;
+           case 'x': acc.mode = acc.read_write; break;
+           case '-': acc.mode = acc.none; break;
+           default: gcc_unreachable ();
+           }
+
+         char *end;
+         acc.ptrarg = strtoul (++m, &end, 10);
+         m = end;
+         if (*m == ',')
+           {
+             acc.sizarg = strtoul (++m, &end, 10);
+             m = end;
+           }
+         else
+           acc.sizarg = UINT_MAX;
+
+         acc.ptr = NULL_TREE;
+         acc.size = NULL_TREE;
+
+         /* Unconditionally add an entry for the required pointer
+            operand of the attribute, and one for the optional size
+            operand when it's specified.  */
+         rwm->put (acc.ptrarg, acc);
+         if (acc.sizarg != UINT_MAX)
+           rwm->put (acc.sizarg, acc);
+       }
+    }
+}
+
 
 #if CHECKING_P
 
@@ -2052,6 +2108,8 @@ struct excl_hash_traits: typed_noop_remove<excl_pair>
     x = value_type (NULL, NULL);
   }
 
+  static const bool empty_zero_p = false;
+
   static void mark_empty (value_type &x)
   {
     x = value_type ("", "");