summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-attribs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-attribs.c')
-rw-r--r--gcc/c-family/c-attribs.c110
1 files changed, 96 insertions, 14 deletions
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 695c58c0a14..2b6845f2cbd 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -51,8 +51,11 @@ static tree handle_common_attribute (tree *, tree, tree, int, bool *);
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
+static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
int, bool *);
+static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
+ int, bool *);
static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
int, bool *);
static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
@@ -285,11 +288,14 @@ const struct attribute_spec c_common_attribute_table[] =
0, 0, true, false, false,
handle_no_address_safety_analysis_attribute,
false },
+ { "no_sanitize", 1, 1, true, false, false,
+ handle_no_sanitize_attribute,
+ false },
{ "no_sanitize_address", 0, 0, true, false, false,
handle_no_sanitize_address_attribute,
false },
{ "no_sanitize_thread", 0, 0, true, false, false,
- handle_no_sanitize_address_attribute,
+ handle_no_sanitize_thread_attribute,
false },
{ "no_sanitize_undefined", 0, 0, true, false, false,
handle_no_sanitize_undefined_attribute,
@@ -547,22 +553,98 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
-/* Handle a "no_sanitize_address" attribute; arguments as in
+/* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */
+
+void
+add_no_sanitize_value (tree node, unsigned int flags)
+{
+ tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
+ if (attr)
+ {
+ unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
+ flags |= old_value;
+
+ if (flags == old_value)
+ return;
+
+ TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
+ }
+ else
+ DECL_ATTRIBUTES (node)
+ = tree_cons (get_identifier ("no_sanitize"),
+ build_int_cst (unsigned_type_node, flags),
+ DECL_ATTRIBUTES (node));
+}
+
+/* Handle a "no_sanitize" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
- bool *no_add_attrs)
+handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
+ bool *no_add_attrs)
{
+ *no_add_attrs = true;
+ tree id = TREE_VALUE (args);
if (TREE_CODE (*node) != FUNCTION_DECL)
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("no_sanitize argument not a string");
+ return NULL_TREE;
+ }
+
+ char *error_value = NULL;
+ char *string = ASTRDUP (TREE_STRING_POINTER (id));
+ unsigned int flags = parse_no_sanitize_attribute (string, &error_value);
+
+ if (error_value)
+ {
+ error ("wrong argument: \"%s\"", error_value);
+ return NULL_TREE;
}
+ add_no_sanitize_value (*node, flags);
+
+ return NULL_TREE;
+}
+
+/* Handle a "no_sanitize_address" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ else
+ add_no_sanitize_value (*node, SANITIZE_ADDRESS);
+
+ return NULL_TREE;
+}
+
+/* Handle a "no_sanitize_thread" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ else
+ add_no_sanitize_value (*node, SANITIZE_THREAD);
+
return NULL_TREE;
}
+
/* Handle a "no_address_safety_analysis" attribute; arguments as in
struct attribute_spec.handler. */
@@ -570,13 +652,12 @@ static tree
handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
bool *no_add_attrs)
{
+ *no_add_attrs = true;
if (TREE_CODE (*node) != FUNCTION_DECL)
warning (OPT_Wattributes, "%qE attribute ignored", name);
- else if (!lookup_attribute ("no_sanitize_address", DECL_ATTRIBUTES (*node)))
- DECL_ATTRIBUTES (*node)
- = tree_cons (get_identifier ("no_sanitize_address"),
- NULL_TREE, DECL_ATTRIBUTES (*node));
- *no_add_attrs = true;
+ else
+ add_no_sanitize_value (*node, SANITIZE_ADDRESS);
+
return NULL_TREE;
}
@@ -587,11 +668,12 @@ static tree
handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
bool *no_add_attrs)
{
+ *no_add_attrs = true;
if (TREE_CODE (*node) != FUNCTION_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ else
+ add_no_sanitize_value (*node,
+ SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
return NULL_TREE;
}