aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2005-07-24 21:38:02 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2005-07-24 21:38:02 +0000
commit104f8784d2e90e6f6da405a8071a59ede65b411a (patch)
tree082c7830d8aa5ffdf45a79a0fea424679a91db14
parent1b8452d093bd8c1642cda1c3369b9f3d7009fe6f (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/c-common.c26
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/c-typeck.c73
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c11
-rw-r--r--gcc/cp/typeck.c11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-1.C40
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-2.C17
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-3.C26
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-4.C32
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-5.C48
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-6.C31
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);
+}