diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-typeck.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c90-const-expr-4.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c99-const-expr-4.c | 11 |
5 files changed, 45 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 888b51027bc..0fa3c22817d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-12-03 Joseph S. Myers <joseph@codesourcery.com> + + * c-typeck.c (default_function_array_conversion, + build_function_call): Allow for CONVERT_EXPR as well as NOP_EXPR. + (build_conditional_expr): Apply integer_zerop to orig_op1 and + orig_op2. Don't check them for NOP_EXPR. + (build_c_cast, convert_for_assignment): Don't check for NOP_EXPR + around integer zero. + 2005-12-03 Alan Modra <amodra@bigpond.net.au> * config/rs6000/rs6000.c (rs6000_stack_t): Remove toc_save_p, diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 735d9e741ed..188e1fe355c 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1467,7 +1467,8 @@ default_function_array_conversion (struct c_expr exp) bool lvalue_array_p; while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR - || TREE_CODE (exp.value) == NOP_EXPR) + || TREE_CODE (exp.value) == NOP_EXPR + || TREE_CODE (exp.value) == CONVERT_EXPR) && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type) { if (TREE_CODE (exp.value) == NON_LVALUE_EXPR) @@ -2161,7 +2162,8 @@ build_function_call (tree function, tree params) expression if necessary. This has the nice side-effect to prevent the tree-inliner from generating invalid assignment trees which may blow up in the RTL expander later. */ - if (TREE_CODE (function) == NOP_EXPR + if ((TREE_CODE (function) == NOP_EXPR + || TREE_CODE (function) == CONVERT_EXPR) && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL && !comptypes (fntype, TREE_TYPE (tem))) @@ -3182,11 +3184,9 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) { if (comp_target_types (type1, type2)) result_type = common_pointer_type (type1, type2); - else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node - && TREE_CODE (orig_op1) != NOP_EXPR) + else if (integer_zerop (orig_op1) && TREE_TYPE (type1) == void_type_node) result_type = qualify_type (type2, type1); - else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node - && TREE_CODE (orig_op2) != NOP_EXPR) + else if (integer_zerop (orig_op2) && TREE_TYPE (type2) == void_type_node) result_type = qualify_type (type1, type2); else if (VOID_TYPE_P (TREE_TYPE (type1))) { @@ -3458,8 +3458,7 @@ build_c_cast (tree type, tree expr) && TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - && !(integer_zerop (value) && TREE_TYPE (otype) == void_type_node - && TREE_CODE (expr) != NOP_EXPR)) + && !(integer_zerop (value) && TREE_TYPE (otype) == void_type_node)) pedwarn ("ISO C forbids conversion of object pointer to function pointer type"); ovalue = value; @@ -3812,9 +3811,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, } /* Can convert integer zero to any pointer type. */ - if (integer_zerop (rhs) - || (TREE_CODE (rhs) == NOP_EXPR - && integer_zerop (TREE_OPERAND (rhs, 0)))) + if (integer_zerop (rhs)) { rhs = null_pointer_node; break; @@ -3952,9 +3949,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE) || (VOID_TYPE_P (ttr) - /* Check TREE_CODE to catch cases like (void *) (char *) 0 - which are not ANSI null ptr constants. */ - && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) + && !integer_zerop (rhs) && TREE_CODE (ttl) == FUNCTION_TYPE))) WARN_FOR_ASSIGNMENT (G_("ISO C forbids passing argument %d of " "%qE between function pointer " @@ -4044,12 +4039,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, /* An explicit constant 0 can convert to a pointer, or one that results from arithmetic, even including a cast to integer type. */ - if (!(TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)) - && - !(TREE_CODE (rhs) == NOP_EXPR - && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE - && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST - && integer_zerop (TREE_OPERAND (rhs, 0)))) + if (!integer_zerop (rhs)) WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes " "pointer from integer without a cast"), G_("assignment makes pointer from integer " diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 415cd85679c..b6c4a8e1e1f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-12-03 Joseph S. Myers <joseph@codesourcery.com> + + * gcc.dg/c90-const-expr-4.c, gcc.dg/c99-const-expr-4.c: New tests. + 2005-12-02 Mark Mitchell <mark@codesourcery.com> PR c++/24173 diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-4.c b/gcc/testsuite/gcc.dg/c90-const-expr-4.c new file mode 100644 index 00000000000..6a449870ed3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-4.c @@ -0,0 +1,11 @@ +/* Test for constant expressions: const variable with value 0 is not a + null pointer constant so the conditional expression should have + type void * and the assignment is OK. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -O2" } */ +int *p; +long *q; +static void *const n = 0; +int j; +void f(void) { q = j ? p : n; } diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-4.c b/gcc/testsuite/gcc.dg/c99-const-expr-4.c new file mode 100644 index 00000000000..f6beaf77a04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-4.c @@ -0,0 +1,11 @@ +/* Test for constant expressions: const variable with value 0 is not a + null pointer constant so the conditional expression should have + type void * and the assignment is OK. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -O2" } */ +int *p; +long *q; +static void *const n = 0; +int j; +void f(void) { q = j ? p : n; } |