c-common.c (binary_op_error): Do not allow NOP_EXPR.

* c-common.c (binary_op_error): Do not allow NOP_EXPR.
	(c_common_truthvalue_conversion): Handle NOP_EXPR the same as
	CONVERT_EXPR.
	(check_function_arguments_recurse): Allow both NOP_EXPR and
	CONVERT_EXPR but check conversions preserve precision.
	* c-typeck.c (pointer_diff): Allow both NOP_EXPR and CONVERT_EXPR
	but check conversions preserve precision.
	(build_unary_op): Don't allow NOP_EXPR.  Use gcc_unreachable () in
	default case.

testsuite:
	* gcc.dg/format/cast-1.c: New test.

From-SVN: r108020
This commit is contained in:
Joseph Myers 2005-12-04 21:45:41 +00:00 committed by Joseph Myers
parent d77314ece6
commit 1344f9a318
5 changed files with 50 additions and 15 deletions

View File

@ -1,3 +1,15 @@
2005-12-04 Joseph S. Myers <joseph@codesourcery.com>
* c-common.c (binary_op_error): Do not allow NOP_EXPR.
(c_common_truthvalue_conversion): Handle NOP_EXPR the same as
CONVERT_EXPR.
(check_function_arguments_recurse): Allow both NOP_EXPR and
CONVERT_EXPR but check conversions preserve precision.
* c-typeck.c (pointer_diff): Allow both NOP_EXPR and CONVERT_EXPR
but check conversions preserve precision.
(build_unary_op): Don't allow NOP_EXPR. Use gcc_unreachable () in
default case.
2005-12-04 Roger Sayle <roger@eyesopen.com>
PR c/7776

View File

@ -1862,8 +1862,7 @@ min_precision (tree value, int unsignedp)
}
/* Print an error message for invalid operands to arith operation
CODE. NOP_EXPR is used as a special case (see
c_common_truthvalue_conversion). */
CODE. */
void
binary_op_error (enum tree_code code)
@ -1872,10 +1871,6 @@ binary_op_error (enum tree_code code)
switch (code)
{
case NOP_EXPR:
error ("invalid truth-value expression");
return;
case PLUS_EXPR:
opname = "+"; break;
case MINUS_EXPR:
@ -2467,13 +2462,12 @@ c_common_truthvalue_conversion (tree expr)
c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)));
case CONVERT_EXPR:
case NOP_EXPR:
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
since that affects how `default_conversion' will behave. */
if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
|| TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
break;
/* Fall through.... */
case NOP_EXPR:
/* If this is widening the argument, we can ignore it. */
if (TYPE_PRECISION (TREE_TYPE (expr))
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
@ -5614,7 +5608,9 @@ check_function_arguments_recurse (void (*callback)
void *ctx, tree param,
unsigned HOST_WIDE_INT param_num)
{
if (TREE_CODE (param) == NOP_EXPR)
if ((TREE_CODE (param) == NOP_EXPR || TREE_CODE (param) == CONVERT_EXPR)
&& (TYPE_PRECISION (TREE_TYPE (param))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (param, 0)))))
{
/* Strip coercion. */
check_function_arguments_recurse (callback, ctx,

View File

@ -2601,8 +2601,18 @@ pointer_diff (tree op0, tree op1)
different mode in place.)
So first try to find a common term here 'by hand'; we want to cover
at least the cases that occur in legal static initializers. */
con0 = TREE_CODE (op0) == NOP_EXPR ? TREE_OPERAND (op0, 0) : op0;
con1 = TREE_CODE (op1) == NOP_EXPR ? TREE_OPERAND (op1, 0) : op1;
if ((TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == CONVERT_EXPR)
&& (TYPE_PRECISION (TREE_TYPE (op0))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
con0 = TREE_OPERAND (op0, 0);
else
con0 = op0;
if ((TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == CONVERT_EXPR)
&& (TYPE_PRECISION (TREE_TYPE (op1))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
con1 = TREE_OPERAND (op1, 0);
else
con1 = op1;
if (TREE_CODE (con0) == PLUS_EXPR)
{
@ -2761,9 +2771,6 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
arg = c_objc_common_truthvalue_conversion (arg);
return invert_truthvalue (arg);
case NOP_EXPR:
break;
case REALPART_EXPR:
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_REALPART (arg);
@ -2941,7 +2948,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
return val;
default:
break;
gcc_unreachable ();
}
if (argtype == 0)

View File

@ -1,3 +1,7 @@
2005-12-04 Joseph S. Myers <joseph@codesourcery.com>
* gcc.dg/format/cast-1.c: New test.
2005-12-04 Roger Sayle <roger@eyesopen.com>
PR c/7776

View File

@ -0,0 +1,16 @@
/* Test for strings cast through integer types: should not be treated
as format strings unless the types are of the same width as
pointers (intptr_t or similar). */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "-Wformat" } */
#include "format.h"
void
f (int x)
{
printf("%s", x); /* { dg-warning "format" } */
printf((char *)(size_t)"%s", x); /* { dg-warning "format" } */
printf((char *)(char)"%s", x);
}