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:
parent
d77314ece6
commit
1344f9a318
@ -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>
|
2005-12-04 Roger Sayle <roger@eyesopen.com>
|
||||||
|
|
||||||
PR c/7776
|
PR c/7776
|
||||||
|
@ -1862,8 +1862,7 @@ min_precision (tree value, int unsignedp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print an error message for invalid operands to arith operation
|
/* Print an error message for invalid operands to arith operation
|
||||||
CODE. NOP_EXPR is used as a special case (see
|
CODE. */
|
||||||
c_common_truthvalue_conversion). */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
binary_op_error (enum tree_code code)
|
binary_op_error (enum tree_code code)
|
||||||
@ -1872,10 +1871,6 @@ binary_op_error (enum tree_code code)
|
|||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case NOP_EXPR:
|
|
||||||
error ("invalid truth-value expression");
|
|
||||||
return;
|
|
||||||
|
|
||||||
case PLUS_EXPR:
|
case PLUS_EXPR:
|
||||||
opname = "+"; break;
|
opname = "+"; break;
|
||||||
case MINUS_EXPR:
|
case MINUS_EXPR:
|
||||||
@ -2467,13 +2462,12 @@ c_common_truthvalue_conversion (tree expr)
|
|||||||
c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)));
|
c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)));
|
||||||
|
|
||||||
case CONVERT_EXPR:
|
case CONVERT_EXPR:
|
||||||
|
case NOP_EXPR:
|
||||||
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
|
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
|
||||||
since that affects how `default_conversion' will behave. */
|
since that affects how `default_conversion' will behave. */
|
||||||
if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
|
if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
|
||||||
|| TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
|
|| TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
|
||||||
break;
|
break;
|
||||||
/* Fall through.... */
|
|
||||||
case NOP_EXPR:
|
|
||||||
/* If this is widening the argument, we can ignore it. */
|
/* If this is widening the argument, we can ignore it. */
|
||||||
if (TYPE_PRECISION (TREE_TYPE (expr))
|
if (TYPE_PRECISION (TREE_TYPE (expr))
|
||||||
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
|
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
|
||||||
@ -5614,7 +5608,9 @@ check_function_arguments_recurse (void (*callback)
|
|||||||
void *ctx, tree param,
|
void *ctx, tree param,
|
||||||
unsigned HOST_WIDE_INT param_num)
|
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. */
|
/* Strip coercion. */
|
||||||
check_function_arguments_recurse (callback, ctx,
|
check_function_arguments_recurse (callback, ctx,
|
||||||
|
@ -2601,8 +2601,18 @@ pointer_diff (tree op0, tree op1)
|
|||||||
different mode in place.)
|
different mode in place.)
|
||||||
So first try to find a common term here 'by hand'; we want to cover
|
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. */
|
at least the cases that occur in legal static initializers. */
|
||||||
con0 = TREE_CODE (op0) == NOP_EXPR ? TREE_OPERAND (op0, 0) : op0;
|
if ((TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == CONVERT_EXPR)
|
||||||
con1 = TREE_CODE (op1) == NOP_EXPR ? TREE_OPERAND (op1, 0) : op1;
|
&& (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)
|
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);
|
arg = c_objc_common_truthvalue_conversion (arg);
|
||||||
return invert_truthvalue (arg);
|
return invert_truthvalue (arg);
|
||||||
|
|
||||||
case NOP_EXPR:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REALPART_EXPR:
|
case REALPART_EXPR:
|
||||||
if (TREE_CODE (arg) == COMPLEX_CST)
|
if (TREE_CODE (arg) == COMPLEX_CST)
|
||||||
return TREE_REALPART (arg);
|
return TREE_REALPART (arg);
|
||||||
@ -2941,7 +2948,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
|
|||||||
return val;
|
return val;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argtype == 0)
|
if (argtype == 0)
|
||||||
|
@ -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>
|
2005-12-04 Roger Sayle <roger@eyesopen.com>
|
||||||
|
|
||||||
PR c/7776
|
PR c/7776
|
||||||
|
16
gcc/testsuite/gcc.dg/format/cast-1.c
Normal file
16
gcc/testsuite/gcc.dg/format/cast-1.c
Normal 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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user