From: Richard Stallman Date: Fri, 13 Aug 1993 05:59:36 +0000 (+0000) Subject: (output_init_element): Don't call default_conversion for a STRING_CST if type is... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fd5d5b94a1a2b798724fd7d92f309ecac8c2eb34;p=gcc.git (output_init_element): Don't call default_conversion for a STRING_CST if type is directly suitable for it. (output_init_element): Don't call default_conversion for a STRING_CST if type is directly suitable for it. (digest_init): Eliminate a lot of code that checks the variable 'element', since element is always 0 in these code paths. (build_c_cast): For (void *) (FOO *) 0, return a nop_expr so it doesn't count as a null pointer constant. (convert_for_assignment, build_binary_op): Pedantically warn about that case if looking for a null_pointer_constant. (build_conditional_expr): Likewise. From-SVN: r5150 --- diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index c748a562cd5..2088f00f8e6 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1,5 +1,5 @@ /* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. @@ -2575,13 +2575,15 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ; else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) { - if (pedantic && !integer_zerop (op0) + /* op0 != orig_op0 detects the case of something + whose value is 0 but which isn't a valid null ptr const. */ + if (pedantic && (!integer_zerop (op0) || op0 != orig_op0) && TREE_CODE (tt1) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); } else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) { - if (pedantic && !integer_zerop (op1) + if (pedantic && (!integer_zerop (op1) || op1 != orig_op1) && TREE_CODE (tt0) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); } @@ -3619,6 +3621,7 @@ build_conditional_expr (ifexp, op1, op2) register enum tree_code code1; register enum tree_code code2; register tree result_type = NULL; + tree orig_op1 = op1, orig_op2 = op2; /* If second operand is omitted, it is the same as the first one; make sure it is calculated only once. */ @@ -3689,9 +3692,11 @@ build_conditional_expr (ifexp, op1, op2) { if (comp_target_types (type1, type2)) result_type = common_type (type1, type2); - else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node) + else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node + && TREE_CODE (orig_op1) != NOP_EXPR) result_type = qualify_type (type2, type1); - else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node) + else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node + && TREE_CODE (orig_op2) != NOP_EXPR) result_type = qualify_type (type1, type2); else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) { @@ -3999,11 +4004,16 @@ build_c_cast (type, expr) } } + /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant. */ + if (pedantic && TREE_CODE (value) == INTEGER_CST + && TREE_CODE (expr) == INTEGER_CST + && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE) + value = non_lvalue (value); + + /* If pedantic, don't let a cast be an lvalue. */ if (value == expr && pedantic) - { - /* If pedantic, don't let a cast be an lvalue. */ - return non_lvalue (value); - } + value = non_lvalue (value); + return value; } @@ -4309,7 +4319,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) && TREE_CODE (ttr) == FUNCTION_TYPE) || (TYPE_MAIN_VARIANT (ttr) == void_type_node - && !integer_zerop (rhs) + /* 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) && TREE_CODE (ttl) == FUNCTION_TYPE))) warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", get_spelling (errtype), funname, parmnum); @@ -4854,7 +4866,6 @@ digest_init (type, init, require_constant, constructor_constant) int require_constant, constructor_constant; { enum tree_code code = TREE_CODE (type); - tree element = 0; tree inside_init = init; if (init == error_mark_node) @@ -4877,15 +4888,12 @@ digest_init (type, init, require_constant, constructor_constant) || typ1 == unsigned_char_type_node || typ1 == unsigned_wchar_type_node || typ1 == signed_wchar_type_node) - && ((inside_init && TREE_CODE (inside_init) == STRING_CST) - || (element && TREE_CODE (element) == STRING_CST))) + && ((inside_init && TREE_CODE (inside_init) == STRING_CST))) { - tree string = element ? element : inside_init; - - if (TREE_TYPE (string) == type) - return string; + if (TREE_TYPE (inside_init) == type) + return inside_init; - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) + if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) != char_type_node) && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) { @@ -4893,7 +4901,7 @@ digest_init (type, init, require_constant, constructor_constant) " `%s'", NULL); return error_mark_node; } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) + if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) == char_type_node) && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) { @@ -4902,7 +4910,7 @@ digest_init (type, init, require_constant, constructor_constant) return error_mark_node; } - TREE_TYPE (string) = type; + TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) { @@ -4911,7 +4919,7 @@ digest_init (type, init, require_constant, constructor_constant) /* Subtract 1 (or sizeof (wchar_t)) because it's ok to ignore the terminating null char that is counted in the length of the constant. */ - if (size < TREE_STRING_LENGTH (string) + if (size < TREE_STRING_LENGTH (inside_init) - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT : 1)) @@ -4919,7 +4927,7 @@ digest_init (type, init, require_constant, constructor_constant) "initializer-string for array of chars%s is too long", " `%s'", NULL); } - return string; + return inside_init; } } @@ -4970,38 +4978,6 @@ digest_init (type, init, require_constant, constructor_constant) return inside_init; } - if (element && (TREE_TYPE (element) == type - || (code == ARRAY_TYPE && TREE_TYPE (element) - && comptypes (TREE_TYPE (element), type)))) - { - if (code == ARRAY_TYPE) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", NULL); - return error_mark_node; - } - if (pedantic && (code == RECORD_TYPE || code == UNION_TYPE)) - pedwarn ("single-expression nonscalar initializer has braces"); - if (optimize && TREE_READONLY (element) && TREE_CODE (element) == VAR_DECL) - element = decl_constant_value (element); - - if (require_constant && ! TREE_CONSTANT (element)) - { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); - element = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); - element = error_mark_node; - } - - return element; - } - /* Handle scalar types, including conversions. */ if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE @@ -5747,6 +5723,9 @@ output_init_element (value, type, field, pending) if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE + && !(TREE_CODE (value) == STRING_CST + && TREE_CODE (type) == ARRAY_TYPE + && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), TYPE_MAIN_VARIANT (type)))) value = default_conversion (value);