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:
parent
1b8452d093
commit
104f8784d2
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
40
gcc/testsuite/g++.dg/warn/miss-format-1.C
Normal file
40
gcc/testsuite/g++.dg/warn/miss-format-1.C
Normal 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" } */
|
||||
}
|
17
gcc/testsuite/g++.dg/warn/miss-format-2.C
Normal file
17
gcc/testsuite/g++.dg/warn/miss-format-2.C
Normal 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);
|
||||
}
|
26
gcc/testsuite/g++.dg/warn/miss-format-3.C
Normal file
26
gcc/testsuite/g++.dg/warn/miss-format-3.C
Normal 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;
|
||||
}
|
32
gcc/testsuite/g++.dg/warn/miss-format-4.C
Normal file
32
gcc/testsuite/g++.dg/warn/miss-format-4.C
Normal 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;
|
||||
}
|
48
gcc/testsuite/g++.dg/warn/miss-format-5.C
Normal file
48
gcc/testsuite/g++.dg/warn/miss-format-5.C
Normal 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;
|
||||
}
|
31
gcc/testsuite/g++.dg/warn/miss-format-6.C
Normal file
31
gcc/testsuite/g++.dg/warn/miss-format-6.C
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user