This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Handle no_sanitize attribute values in the right way (PR sanitizer/85556).
- From: Martin Liška <mliska at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Thu, 10 May 2018 11:28:15 +0200
- Subject: [PATCH] Handle no_sanitize attribute values in the right way (PR sanitizer/85556).
Hi.
Parsing of no_sanitize attribute now supports
__attribute__((no_sanitize("address,undefined")))
which is wrong. And on the other hand this is not recognized:
__attribute__((no_sanitize("address", "undefined")))
Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Then I would like
to backport that to GCC 8 branch.
Ready to be installed?
Martin
gcc/ChangeLog:
2018-05-10 Martin Liska <mliska@suse.cz>
PR sanitizer/85556
* opts.c (parse_no_sanitize_attribute): Handle only a sinle
option value.
gcc/c-family/ChangeLog:
2018-05-10 Martin Liska <mliska@suse.cz>
PR sanitizer/85556
* c-attribs.c (handle_no_sanitize_attribute): Iterate all
TREE_LIST values.
gcc/testsuite/ChangeLog:
2018-05-10 Martin Liska <mliska@suse.cz>
PR sanitizer/85556
* c-c++-common/ubsan/attrib-6.c: New test.
---
gcc/c-family/c-attribs.c | 20 +++++++++++--------
gcc/opts.c | 30 +++++++++++------------------
gcc/testsuite/c-c++-common/ubsan/attrib-6.c | 22 +++++++++++++++++++++
3 files changed, 45 insertions(+), 27 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/ubsan/attrib-6.c
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index e0630885cca..744315eec86 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -403,7 +403,7 @@ const struct attribute_spec c_common_attribute_table[] =
0, 0, true, false, false, false,
handle_no_address_safety_analysis_attribute,
NULL },
- { "no_sanitize", 1, 1, true, false, false, false,
+ { "no_sanitize", 1, -1, true, false, false, false,
handle_no_sanitize_attribute, NULL },
{ "no_sanitize_address", 0, 0, true, false, false, false,
handle_no_sanitize_address_attribute, NULL },
@@ -683,22 +683,26 @@ static tree
handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
bool *no_add_attrs)
{
+ unsigned int flags = 0;
*no_add_attrs = true;
- tree id = TREE_VALUE (args);
if (TREE_CODE (*node) != FUNCTION_DECL)
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
return NULL_TREE;
}
- if (TREE_CODE (id) != STRING_CST)
+ for (; args; args = TREE_CHAIN (args))
{
- error ("no_sanitize argument not a string");
- return NULL_TREE;
- }
+ tree id = TREE_VALUE (args);
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("no_sanitize argument not a string");
+ return NULL_TREE;
+ }
- char *string = ASTRDUP (TREE_STRING_POINTER (id));
- unsigned int flags = parse_no_sanitize_attribute (string);
+ char *string = ASTRDUP (TREE_STRING_POINTER (id));
+ flags |= parse_no_sanitize_attribute (string);
+ }
add_no_sanitize_value (*node, flags);
diff --git a/gcc/opts.c b/gcc/opts.c
index 33efcc0d6e7..f999dccd009 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1748,33 +1748,25 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
return flags;
}
-/* Parse string values of no_sanitize attribute passed in VALUE.
- Values are separated with comma. */
+/* Parse string value of no_sanitize attribute passed in VALUE. */
unsigned int
parse_no_sanitize_attribute (char *value)
{
unsigned int flags = 0;
unsigned int i;
- char *q = strtok (value, ",");
- while (q != NULL)
- {
- for (i = 0; sanitizer_opts[i].name != NULL; ++i)
- if (strcmp (sanitizer_opts[i].name, q) == 0)
- {
- flags |= sanitizer_opts[i].flag;
- if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
- flags |= SANITIZE_UNDEFINED_NONDEFAULT;
- break;
- }
-
- if (sanitizer_opts[i].name == NULL)
- warning (OPT_Wattributes,
- "%<%s%> attribute directive ignored", q);
+ for (i = 0; sanitizer_opts[i].name != NULL; ++i)
+ if (strcmp (sanitizer_opts[i].name, value) == 0)
+ {
+ flags |= sanitizer_opts[i].flag;
+ if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
+ flags |= SANITIZE_UNDEFINED_NONDEFAULT;
+ break;
+ }
- q = strtok (NULL, ",");
- }
+ if (sanitizer_opts[i].name == NULL)
+ warning (OPT_Wattributes, "%<%s%> attribute directive ignored", value);
return flags;
}
diff --git a/gcc/testsuite/c-c++-common/ubsan/attrib-6.c b/gcc/testsuite/c-c++-common/ubsan/attrib-6.c
new file mode 100644
index 00000000000..ac08dc219ec
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/attrib-6.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+static void __attribute__((no_sanitize("foobar")))
+foo (void) { /* { dg-warning "attribute directive ignored" } */
+}
+
+static void __attribute__((no_sanitize("address,undefined")))
+foo2 (void) { /* { dg-warning ".address,undefined. attribute directive ignored" } */
+}
+
+static void __attribute__((no_sanitize("address", "undefined")))
+foo3 (void) {
+}
+
+static void __attribute__((no_sanitize("address", "address", "")))
+foo4 (void) { /* { dg-warning ".. attribute directive ignored" } */
+}
+
+static void __attribute__((no_sanitize("address", "address", "address,address")))
+foo5 (void) { /* { dg-warning ".address,address. attribute directive ignored" } */
+}