diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-02-19 18:08:05 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-02-19 18:08:05 -0500 |
commit | 5651ad62b08096a155a7e394c7494f5ff1c04f4f (patch) | |
tree | a48f3629d988aa7903069e791a60b8446d567b4e /gcc/testsuite/c-c++-common/analyzer | |
parent | eb37ea529745c38dcf86c3cdbedb66df69ea9e35 (diff) | |
download | gcc-5651ad62b08096a155a7e394c7494f5ff1c04f4f.zip gcc-5651ad62b08096a155a7e394c7494f5ff1c04f4f.tar.gz gcc-5651ad62b08096a155a7e394c7494f5ff1c04f4f.tar.bz2 |
analyzer: fix -Wanalyzer-va-arg-type-mismatch false +ve on int types [PR111289]
gcc/analyzer/ChangeLog:
PR analyzer/111289
* varargs.cc (representable_in_integral_type_p): New.
(va_arg_compatible_types_p): Add "arg_sval" param. Handle integer
types.
(kf_va_arg::impl_call_pre): Pass arg_sval to
va_arg_compatible_types_p.
gcc/testsuite/ChangeLog:
PR analyzer/111289
* c-c++-common/analyzer/stdarg-pr111289-int.c: New test.
* c-c++-common/analyzer/stdarg-pr111289-ptr.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/testsuite/c-c++-common/analyzer')
-rw-r--r-- | gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-int.c | 69 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-ptr.c | 39 |
2 files changed, 108 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-int.c b/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-int.c new file mode 100644 index 0000000..33d8316 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-int.c @@ -0,0 +1,69 @@ +#include <stdarg.h> +#include <stdint.h> +#include <limits.h> + +typedef unsigned int mode_t; + +extern void openat (int, const char *, int, mode_t); + +/* Signed vs unsigned of same integral type. */ + +static void +test_1 (char const *name, ...) +{ + va_list arg; + va_start (arg, name); + + mode_t mode = va_arg (arg, mode_t); /* { dg-bogus "-Wanalyzer-va-arg-type-mismatch" } */ + + va_end (arg); + openat (-42, name, 0, mode); +} + +void +call_test_1 () +{ + test_1 ("nonexist.ent/", 0600); +} + +/* Not the same size: small enough for int promotion. */ + +int16_t global_2; + +static void +test_2 (char const *name, ...) +{ + va_list arg; + va_start (arg, name); + + global_2 = va_arg (arg, int16_t); /* { dg-warning "promoted to 'int'" } */ + + va_end (arg); +} + +void +call_test_2 () +{ + test_2 ("nonexist.ent/", 42); +} + +/* Not the same size: too big for int promotion. */ + +long long global_3; + +static void +test_3 (char const *name, ...) +{ + va_list arg; + va_start (arg, name); + + global_3 = va_arg (arg, long long); /* { dg-warning "'va_arg' expected 'long long int' but received 'int' for variadic argument 1 of 'arg'" } */ + + va_end (arg); +} + +void +call_test_3 () +{ + test_3 ("nonexist.ent/", 42); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-ptr.c b/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-ptr.c new file mode 100644 index 0000000..7bdbf25 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/stdarg-pr111289-ptr.c @@ -0,0 +1,39 @@ +#include <stdarg.h> + +static void * +test_1 (const char *fmt, ...) +{ + va_list arg; + va_start (arg, fmt); + + void *p = va_arg (arg, void *); /* { dg-bogus "-Wanalyzer-va-arg-type-mismatch" } */ + + va_end (arg); + + return p; +} + +void * +call_test_1 () +{ + return test_1 ("fmt", "foo"); +} + +static char * +test_2 (const char *fmt, ...) +{ + va_list arg; + va_start (arg, fmt); + + char *p = va_arg (arg, char *); /* { dg-bogus "-Wanalyzer-va-arg-type-mismatch" } */ + + va_end (arg); + + return p; +} + +char * +call_test_2 (void *q) +{ + return test_2 ("fmt", q); +} |