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
This commit is contained in:
Kaveh R. Ghazi 2005-07-24 21:38:02 +00:00 committed by Kaveh Ghazi
parent 1b8452d093
commit 104f8784d2
14 changed files with 290 additions and 44 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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 *

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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" } */
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}