OSDN Git Service

* c-common.c (binary_op_error): Do not allow NOP_EXPR.
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Dec 2005 21:45:41 +0000 (21:45 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Dec 2005 21:45:41 +0000 (21:45 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108020 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-common.c
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format/cast-1.c [new file with mode: 0644]

index d8fc531..31ac760 100644 (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
index 898f394..27934dd 100644 (file)
@@ -1862,8 +1862,7 @@ min_precision (tree value, int unsignedp)
 }
 \f
 /* 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,
index 062de7c..e4e21dc 100644 (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)
index f08c252..93e36dc 100644 (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
diff --git a/gcc/testsuite/gcc.dg/format/cast-1.c b/gcc/testsuite/gcc.dg/format/cast-1.c
new file mode 100644 (file)
index 0000000..78a4f52
--- /dev/null
@@ -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);
+}