diff options
author | Martin Sebor <msebor@redhat.com> | 2020-03-01 17:41:45 -0700 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-03-01 17:41:45 -0700 |
commit | a499c2f899961f2c09db2dc33e60b66e8d770092 (patch) | |
tree | b4e1280ce09a78f7b1a84f3e921d48f47aef1ef2 | |
parent | 1e9369c5dcf301e090d3a83e2c210cd6b96ac08c (diff) | |
download | gcc-a499c2f899961f2c09db2dc33e60b66e8d770092.zip gcc-a499c2f899961f2c09db2dc33e60b66e8d770092.tar.gz gcc-a499c2f899961f2c09db2dc33e60b66e8d770092.tar.bz2 |
PR c/93812 - ICE on redeclaration of an attribute format function without protoype
gcc/c/ChangeLog:
PR c/93812
* c-typeck.c (build_functype_attribute_variant): New function.
(composite_type): Call it.
gcc/testsuite/ChangeLog:
PR c/93812
* gcc.dg/format/proto.c: New test.
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/format/proto.c | 89 |
4 files changed, 124 insertions, 3 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 83bf651..effb71b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-03-01 Martin Sebor <msebor@redhat.com> + + PR c/93812 + * c-typeck.c (build_functype_attribute_variant): New function. + (composite_type): Call it. + 2020-02-25 Jakub Jelinek <jakub@redhat.com> PR other/93912 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 8df0849..308fcff 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -353,7 +353,28 @@ c_vla_type_p (const_tree t) return true; return false; } - + +/* If NTYPE is a type of a non-variadic function with a prototype + and OTYPE is a type of a function without a prototype and ATTRS + contains attribute format, diagnosess and removes it from ATTRS. + Returns the result of build_type_attribute_variant of NTYPE and + the (possibly) modified ATTRS. */ + +static tree +build_functype_attribute_variant (tree ntype, tree otype, tree attrs) +{ + if (!prototype_p (otype) + && prototype_p (ntype) + && lookup_attribute ("format", attrs)) + { + warning_at (input_location, OPT_Wattributes, + "%qs attribute cannot be applied to a function that " + "does not take variable arguments", "format"); + attrs = remove_attribute ("format", attrs); + } + return build_type_attribute_variant (ntype, attrs); + +} /* Return the composite type of two compatible types. We assume that comptypes has already been done and returned @@ -504,9 +525,9 @@ composite_type (tree t1, tree t2) /* Save space: see if the result is identical to one of the args. */ if (valtype == TREE_TYPE (t1) && !TYPE_ARG_TYPES (t2)) - return build_type_attribute_variant (t1, attributes); + return build_functype_attribute_variant (t1, t2, attributes); if (valtype == TREE_TYPE (t2) && !TYPE_ARG_TYPES (t1)) - return build_type_attribute_variant (t2, attributes); + return build_functype_attribute_variant (t2, t1, attributes); /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == NULL_TREE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e73cc6..a6524be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2020-03-01 Martin Sebor <msebor@redhat.com> + PR c/93812 + * gcc.dg/format/proto.c: New test. + +2020-03-01 Martin Sebor <msebor@redhat.com> + PR middle-end/93829 * gcc.dg/Wstringop-overflow-32.c: New test. diff --git a/gcc/testsuite/gcc.dg/format/proto.c b/gcc/testsuite/gcc.dg/format/proto.c new file mode 100644 index 0000000..b2050c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/proto.c @@ -0,0 +1,89 @@ +/* PR c/93812 - ICE on redeclaration of an attribute format function without + protoype + It's not clear that attribute format should be accepted on functions + without a prototype. If it's decided that it shouldn't be the tests + here will need to be adjusted. + { dg-do compile } + { dg-options "-Wall" } */ + +#define FMT(n1, n2) __attribute__((__format__(__printf__, n1, n2))) + +// Exercise function declarations. +FMT (1, 2) void print1 (); + +FMT (2, 3) void print2 (); + void print2 (); + +FMT (3, 4) void print3 (); +FMT (3, 4) void print3 (); + +FMT (1, 2) void print4 (); + void print4 (void); // { dg-warning "'format' attribute cannot be applied to a function that does not take variable arguments" } + + void print5 (); +FMT (1, 2) void print5 (void); // { dg-warning "\\\[-Wattributes" } + +FMT (1, 2) void print6 (); + void print6 (const char*, ...); // { dg-error "conflicting types" } + + void print7 (const char*, ...); +FMT (1, 2) void print7 (); // { dg-error "conflicting types" } + + +// Exercise function calls. +void test_print (void) +{ + print1 ("%i %s", 123, ""); + print1 ("%s %i", 123, 123); // { dg-warning "\\\[-Wformat" } + + print2 (0, "%s %i", "", 123); + print2 (1, "%i %s", "", 123); // { dg-warning "\\\[-Wformat" } + + print3 (0, 1, "%s %i", "", 123); + print3 (1, 2, "%i %s", "", 123); // { dg-warning "\\\[-Wformat" } + + // Just verify there's no ICE. + print4 (); + print5 (); + print6 ("%i %s", 123, ""); +} + + +// Exercise declarations of pointers to functions. +FMT (1, 2) void (*pfprint1)(); + +FMT (2, 3) void (*pfprint2)(); + void (*pfprint2)(); + +FMT (3, 4) void (*pfprint3)(); +FMT (3, 4) void (*pfprint3)(); + +FMT (1, 2) void (*pfprint4)(); + void (*pfprint4)(void); // { dg-warning "'format' attribute cannot be applied to a function that does not take variable arguments" } + + void (*pfprint5)(); +FMT (1, 2) void (*pfprint5)(void); // { dg-warning "\\\[-Wattributes" } + +FMT (1, 2) void (*pfprint6)(); + void (*pfprint6)(const char*, ...); // { dg-error "conflicting types" } + + void (*pfprint7)(const char*, ...); +FMT (1, 2) void (*pfprint7)(); // { dg-error "conflicting types" } + +// Exercise calls via function pointers. +void test_pfprint (void) +{ + pfprint1 ("%i %s", 123, ""); + pfprint1 ("%s %i", 123, 123); // { dg-warning "\\\[-Wformat" } + + pfprint2 (0, "%s %i", "", 123); + pfprint2 (1, "%i %s", "", 123); // { dg-warning "\\\[-Wformat" } + + pfprint3 (0, 1, "%s %i", "", 123); + pfprint3 (1, 2, "%i %s", "", 123); // { dg-warning "\\\[-Wformat" } + + // Just verify there's no ICE. + pfprint4 (); + pfprint5 (); + pfprint6 ("%i %s", 123, ""); +} |