aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-06-15 22:51:52 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-06-15 23:16:21 +0200
commit90f2a111413a6d4264335046d68ffa19725864b6 (patch)
tree566e5fee798421401ae158412b179351a25e7c52 /gcc/d
parentdc9b92facf87a6f2d8b0e5d5fc404f30c3b15a74 (diff)
downloadgcc-90f2a111413a6d4264335046d68ffa19725864b6.zip
gcc-90f2a111413a6d4264335046d68ffa19725864b6.tar.gz
gcc-90f2a111413a6d4264335046d68ffa19725864b6.tar.bz2
d: Add `@no_sanitize' attribute to compiler and library.
The `@no_sanitize' attribute disables a particular sanitizer for this function, analogous to `__attribute__((no_sanitize))'. The library also defines `@noSanitize' to be compatible with the LLVM D compiler's `ldc.attributes'. gcc/d/ChangeLog: * d-attribs.cc (d_langhook_attribute_table): Add no_sanitize. (d_handle_no_sanitize_attribute): New function. libphobos/ChangeLog: * libdruntime/gcc/attributes.d (no_sanitize): Define. (noSanitize): Define. gcc/testsuite/ChangeLog: * gdc.dg/asan/attr_no_sanitize1.d: New test. * gdc.dg/ubsan/attr_no_sanitize2.d: New test.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/d-attribs.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc
index 4c6e7a7..4b54426 100644
--- a/gcc/d/d-attribs.cc
+++ b/gcc/d/d-attribs.cc
@@ -78,6 +78,7 @@ static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *);
static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *);
static tree d_handle_used_attribute (tree *, tree, tree, int, bool *);
static tree d_handle_visibility_attribute (tree *, tree, tree, int, bool *);
+static tree d_handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
@@ -220,6 +221,8 @@ const attribute_spec d_langhook_attribute_table[] =
d_handle_alloc_size_attribute, attr_alloc_exclusions),
ATTR_SPEC ("cold", 0, 0, true, false, false, false,
d_handle_cold_attribute, attr_cold_hot_exclusions),
+ ATTR_SPEC ("no_sanitize", 1, -1, true, false, false, false,
+ d_handle_no_sanitize_attribute, NULL),
ATTR_SPEC ("restrict", 0, 0, true, false, false, false,
d_handle_restrict_attribute, NULL),
ATTR_SPEC ("used", 0, 0, true, false, false, false,
@@ -1364,6 +1367,55 @@ d_handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
return NULL_TREE;
}
+/* Handle a "no_sanitize" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+d_handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
+ bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ return NULL_TREE;
+ }
+
+ unsigned int flags = 0;
+ for (; args; args = TREE_CHAIN (args))
+ {
+ tree id = TREE_VALUE (args);
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("%qE argument not a string", name);
+ return NULL_TREE;
+ }
+
+ char *string = ASTRDUP (TREE_STRING_POINTER (id));
+ flags |= parse_no_sanitize_attribute (string);
+ }
+
+ /* Store the flags argument back into no_sanitize attribute as an integer,
+ merge existing flags if no_sanitize was previously handled. */
+ if (tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (*node)))
+ {
+ unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
+ flags |= old_value;
+
+ if (flags != old_value)
+ TREE_VALUE (attr) = build_int_cst (d_uint_type, flags);
+ }
+ else
+ {
+ DECL_ATTRIBUTES (*node) = tree_cons (get_identifier ("no_sanitize"),
+ build_int_cst (d_uint_type, flags),
+ DECL_ATTRIBUTES (*node));
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "restrict" attribute; arguments as in
struct attribute_spec.handler. */