c-typeck.c (default_function_array_conversion, [...]): Allow for CONVERT_EXPR as well as NOP_EXPR.

* 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.

testsuite:
	* gcc.dg/c90-const-expr-4.c, gcc.dg/c99-const-expr-4.c: New tests.

From-SVN: r107990
This commit is contained in:
Joseph Myers 2005-12-03 01:25:42 +00:00 committed by Joseph Myers
parent 3820178b94
commit 718699e900
5 changed files with 45 additions and 20 deletions

View File

@ -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,

View File

@ -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 "

View File

@ -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

View File

@ -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; }

View File

@ -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; }