diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2005-07-24 21:38:02 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2005-07-24 21:38:02 +0000 |
commit | 104f8784d2e90e6f6da405a8071a59ede65b411a (patch) | |
tree | 082c7830d8aa5ffdf45a79a0fea424679a91db14 | |
parent | 1b8452d093bd8c1642cda1c3369b9f3d7009fe6f (diff) | |
download | gcc-104f8784d2e90e6f6da405a8071a59ede65b411a.zip gcc-104f8784d2e90e6f6da405a8071a59ede65b411a.tar.gz gcc-104f8784d2e90e6f6da405a8071a59ede65b411a.tar.bz2 |
c-common.c (check_missing_format_attribute): New.
* c-common.c (check_missing_format_attribute): New.
* c-common.h (check_missing_format_attribute): Likewise.
* c-typeck.c (convert_for_assignment): Use it.
cp:
* call.c (convert_for_arg_passing): Check function pointers when
-Wmissing-format-attribute is activated.
* typeck.c (convert_for_assignment): Likewise.
testsuite:
* g++.dg/warn/miss-format-1.C, g++.dg/warn/miss-format-2.C,
g++.dg/warn/miss-format-3.C, g++.dg/warn/miss-format-4.C,
g++.dg/warn/miss-format-5.C, g++.dg/warn/miss-format-6.C: New.
From-SVN: r102338
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-common.c | 26 | ||||
-rw-r--r-- | gcc/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c-typeck.c | 73 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 11 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-1.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-2.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-3.C | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-4.C | 32 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-5.C | 48 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/miss-format-6.C | 31 |
14 files changed, 290 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d86dc82..42c8c2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * c-common.c (check_missing_format_attribute): New. + * c-common.h (check_missing_format_attribute): Likewise. + * c-typeck.c (convert_for_assignment): Use it. + 2005-07-24 Andreas Schwab <schwab@suse.de> * config/m68k/m68k.md ("extendqidi2"): When source is an address diff --git a/gcc/c-common.c b/gcc/c-common.c index 8646b4c..10350f3 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -6208,4 +6208,30 @@ same_scalar_type_ignoring_signedness (tree t1, tree t2) == lang_hooks.types.signed_type (t2); } +/* Check for missing format attributes on function pointers. LTYPE is + the new type or left-hand side type. RTYPE is the old type or + right-hand side type. Returns TRUE if LTYPE is missing the desired + attribute. */ + +bool +check_missing_format_attribute (tree ltype, tree rtype) +{ + tree const ttr = TREE_TYPE (rtype), ttl = TREE_TYPE (ltype); + tree ra; + + for (ra = TYPE_ATTRIBUTES (ttr); ra; ra = TREE_CHAIN (ra)) + if (is_attribute_p ("format", TREE_PURPOSE (ra))) + break; + if (ra) + { + tree la; + for (la = TYPE_ATTRIBUTES (ttl); la; la = TREE_CHAIN (la)) + if (is_attribute_p ("format", TREE_PURPOSE (la))) + break; + return !la; + } + else + return false; +} + #include "gt-c-common.h" diff --git a/gcc/c-common.h b/gcc/c-common.h index 76a9650..4e8485a 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -925,6 +925,7 @@ extern void init_pp_output (FILE *); extern void preprocess_file (cpp_reader *); extern void pp_file_change (const struct line_map *); extern void pp_dir_change (cpp_reader *, const char *); +extern bool check_missing_format_attribute (tree, tree); /* In order for the format checking to accept the C frontend diagnostic framework extensions, you must include this file before diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index cb28838..7e98384 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3802,51 +3802,36 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, /* Check if the right-hand side has a format attribute but the left-hand side doesn't. */ - if (warn_missing_format_attribute) + if (warn_missing_format_attribute + && check_missing_format_attribute (type, rhstype)) { - tree rattrs = TYPE_ATTRIBUTES (ttr), ra; - for (ra = rattrs; ra; ra = TREE_CHAIN (ra)) - { - if (is_attribute_p ("format", TREE_PURPOSE (ra))) - break; - } - if (ra) - { - tree lattrs = TYPE_ATTRIBUTES (ttl), la; - for (la = lattrs; la; la = TREE_CHAIN (la)) - { - if (is_attribute_p ("format", TREE_PURPOSE (la))) - break; - } - if (!la) - switch (errtype) - { - case ic_argpass: - case ic_argpass_nonproto: - warning (OPT_Wmissing_format_attribute, - "argument %d of %qE might be " - "a candidate for a format attribute", - parmnum, rname); - break; - case ic_assign: - warning (OPT_Wmissing_format_attribute, - "assignment left-hand side might be " - "a candidate for a format attribute"); - break; - case ic_init: - warning (OPT_Wmissing_format_attribute, - "initialization left-hand side might be " - "a candidate for a format attribute"); - break; - case ic_return: - warning (OPT_Wmissing_format_attribute, - "return type might be " - "a candidate for a format attribute"); - break; - default: - gcc_unreachable (); - } - } + switch (errtype) + { + case ic_argpass: + case ic_argpass_nonproto: + warning (OPT_Wmissing_format_attribute, + "argument %d of %qE might be " + "a candidate for a format attribute", + parmnum, rname); + break; + case ic_assign: + warning (OPT_Wmissing_format_attribute, + "assignment left-hand side might be " + "a candidate for a format attribute"); + break; + case ic_init: + warning (OPT_Wmissing_format_attribute, + "initialization left-hand side might be " + "a candidate for a format attribute"); + break; + case ic_return: + warning (OPT_Wmissing_format_attribute, + "return type might be " + "a candidate for a format attribute"); + break; + default: + gcc_unreachable (); + } } /* Any non-function converts to a [const][volatile] void * diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 485de2f..003fbab 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * call.c (convert_for_arg_passing): Check function pointers when + -Wmissing-format-attribute is activated. + * typeck.c (convert_for_assignment): Likewise. + 2005-07-22 Manfred Hollstein <mh@suse.com> * parser.c (cp_parser_declaration): Fix unitialised warnings. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4e5ccff..609fe45 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4601,6 +4601,17 @@ convert_for_arg_passing (tree type, tree val) && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) val = perform_integral_promotions (val); + if (warn_missing_format_attribute) + { + tree rhstype = TREE_TYPE (val); + const enum tree_code coder = TREE_CODE (rhstype); + const enum tree_code codel = TREE_CODE (type); + if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE) + && coder == codel + && check_missing_format_attribute (type, rhstype)) + warning (OPT_Wmissing_format_attribute, + "argument of function call might be a candidate for a format attribute"); + } return val; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9a14f48..62f5297 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5948,6 +5948,17 @@ convert_for_assignment (tree type, tree rhs, return error_mark_node; } } + if (warn_missing_format_attribute) + { + const enum tree_code codel = TREE_CODE (type); + if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE) + && coder == codel + && check_missing_format_attribute (type, rhstype)) + warning (OPT_Wmissing_format_attribute, + "%s might be a candidate for a format attribute", + errtype); + } + return perform_implicit_conversion (strip_top_quals (type), rhs); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2986250..19d3975 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * g++.dg/warn/miss-format-1.C, g++.dg/warn/miss-format-2.C, + g++.dg/warn/miss-format-3.C, g++.dg/warn/miss-format-4.C, + g++.dg/warn/miss-format-5.C, g++.dg/warn/miss-format-6.C: New. + 2005-07-23 Jerry DeLisle <jvdelisle@verizon.net> * gfortran.fortran-torture/execute/nan_inf_fmt.f90: Revise test to diff --git a/gcc/testsuite/g++.dg/warn/miss-format-1.C b/gcc/testsuite/g++.dg/warn/miss-format-1.C new file mode 100644 index 0000000..f69e18f --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-1.C @@ -0,0 +1,40 @@ +/* Test for warnings for missing format attributes. */ +/* Origin: Joseph Myers <jsm28@cam.ac.uk> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdio.h> +#include <stdarg.h> + +void +foo (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); /* { dg-warning "candidate" "printf attribute warning" } */ + va_end (ap); +} + +void +bar (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vscanf (fmt, ap); /* { dg-warning "candidate" "scanf attribute warning" } */ + va_end (ap); +} + +__attribute__((__format__(__printf__, 1, 2))) void +foo2 (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); +} + +void +vfoo (const char *fmt, va_list arg) +{ + vprintf (fmt, arg); /* { dg-warning "candidate" "printf attribute warning 2" } */ +} diff --git a/gcc/testsuite/g++.dg/warn/miss-format-2.C b/gcc/testsuite/g++.dg/warn/miss-format-2.C new file mode 100644 index 0000000..bd7f11b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-2.C @@ -0,0 +1,17 @@ +/* Test for warnings for missing format attributes. Don't warn if no + relevant parameters for a format attribute; see c/1017. */ +/* Origin: Joseph Myers <jsm28@cam.ac.uk> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdio.h> +#include <stdarg.h> + +void +foo (int i, ...) +{ + va_list ap; + va_start (ap, i); + vprintf ("Foo %s bar %s", ap); /* { dg-bogus "candidate" "bogus printf attribute warning" } */ + va_end (ap); +} diff --git a/gcc/testsuite/g++.dg/warn/miss-format-3.C b/gcc/testsuite/g++.dg/warn/miss-format-3.C new file mode 100644 index 0000000..0f61400 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-3.C @@ -0,0 +1,26 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi <ghazi@caip.rutgers.edu> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdarg.h> + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; + +void +foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + noattr_t na1 = na; + noattr_t na2 = a; /* { dg-warning "candidate" "initialization warning" } */ + attr_t a1 = na; + attr_t a2 = a; + + vnoattr_t vna1 = vna; + vnoattr_t vna2 = va; /* { dg-warning "candidate" "initialization warning" } */ + vattr_t va1 = vna; + vattr_t va2 = va; +} diff --git a/gcc/testsuite/g++.dg/warn/miss-format-4.C b/gcc/testsuite/g++.dg/warn/miss-format-4.C new file mode 100644 index 0000000..1a89abd --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-4.C @@ -0,0 +1,32 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi <ghazi@caip.rutgers.edu> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdarg.h> + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; + +void +foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + noattr_t na1, na2; + attr_t a1, a2; + + vnoattr_t vna1, vna2; + vattr_t va1, va2; + + na1 = na; + na2 = a; /* { dg-warning "candidate" "assignment warning" } */ + a1 = na; + a2 = a; + + vna1 = vna; + vna2 = va; /* { dg-warning "candidate" "assignment warning" } */ + va1 = vna; + va1 = va; +} diff --git a/gcc/testsuite/g++.dg/warn/miss-format-5.C b/gcc/testsuite/g++.dg/warn/miss-format-5.C new file mode 100644 index 0000000..452e812 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-5.C @@ -0,0 +1,48 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi <ghazi@caip.rutgers.edu> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdarg.h> + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; + +noattr_t +foo1 (noattr_t na, attr_t a, int i) +{ + if (i) + return na; + else + return a; /* { dg-warning "candidate" "return type warning" } */ +} + +attr_t +foo2 (noattr_t na, attr_t a, int i) +{ + if (i) + return na; + else + return a; +} + +vnoattr_t +foo3 (vnoattr_t vna, vattr_t va, int i) +{ + if (i) + return vna; + else + return va; /* { dg-warning "candidate" "return type warning" } */ +} + +vattr_t +foo4 (vnoattr_t vna, vattr_t va, int i) +{ + if (i) + return vna; + else + return va; +} diff --git a/gcc/testsuite/g++.dg/warn/miss-format-6.C b/gcc/testsuite/g++.dg/warn/miss-format-6.C new file mode 100644 index 0000000..f38e4ca --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/miss-format-6.C @@ -0,0 +1,31 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi <ghazi@caip.rutgers.edu> */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-format-attribute" } */ + +#include <stdarg.h> + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; + +extern void foo1 (noattr_t); +extern void foo2 (attr_t); +extern void foo3 (vnoattr_t); +extern void foo4 (vattr_t); + +void +foo (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + foo1 (na); + foo1 (a); /* { dg-warning "candidate" "parameter passing warning" } */ + foo2 (na); + foo2 (a); + + foo3 (vna); + foo3 (va); /* { dg-warning "candidate" "parameter passing warning" } */ + foo4 (vna); + foo4 (va); +} |