diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/c-common.c | 14 | ||||
-rw-r--r-- | gcc/c-common.h | 2 | ||||
-rw-r--r-- | gcc/c-tree.h | 1 | ||||
-rw-r--r-- | gcc/c-typeck.c | 77 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 |
7 files changed, 77 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fcac50b2ae7..8bd9d404a78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2005-03-23 Joseph S. Myers <joseph@codesourcery.com> + + * c-common.h (default_conversion): Remove. + (perform_integral_promotions): Add. + * c-tree.h (default_conversion): Add. + * c-typeck.c (perform_integral_promotions): New, split out from + default_conversion. + * c-common.c (check_case_value): Use perform_integral_promotions, + not default_conversion. + (c_add_case_label): Don't continue processing case label after + found to be pointer. + 2005-03-23 Mark Mitchell <mark@codesourcery.com> * gcc.c (do_spec_1): Do not add a -L path for a directory in diff --git a/gcc/c-common.c b/gcc/c-common.c index a18520d9e0d..d4b9d5cda8e 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1427,15 +1427,14 @@ check_case_value (tree value) value = fold (value); } - if (TREE_CODE (value) != INTEGER_CST - && value != error_mark_node) + if (TREE_CODE (value) == INTEGER_CST) + /* Promote char or short to int. */ + value = perform_integral_promotions (value); + else if (value != error_mark_node) { error ("case label does not reduce to an integer constant"); value = error_mark_node; } - else - /* Promote char or short to int. */ - value = default_conversion (value); constant_expression_warning (value); @@ -3514,7 +3513,10 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type, && POINTER_TYPE_P (TREE_TYPE (low_value))) || (high_value && TREE_TYPE (high_value) && POINTER_TYPE_P (TREE_TYPE (high_value)))) - error ("pointers are not permitted as case values"); + { + error ("pointers are not permitted as case values"); + goto error_out; + } /* Case ranges are a GNU extension. */ if (high_value && pedantic) diff --git a/gcc/c-common.h b/gcc/c-common.h index 64daf34b440..63dcb10b40c 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -808,7 +808,7 @@ extern tree build_break_stmt (void); extern tree build_unary_op (enum tree_code, tree, int); extern tree build_binary_op (enum tree_code, tree, tree, int); -extern tree default_conversion (tree); +extern tree perform_integral_promotions (tree); /* Given two integer or real types, return the type for their sum. Given two compatible ANSI C types, returns the merged type. */ diff --git a/gcc/c-tree.h b/gcc/c-tree.h index adace275c38..bbfed6abbaf 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -460,6 +460,7 @@ extern int comptypes (tree, tree); extern bool c_mark_addressable (tree); extern void c_incomplete_type_error (tree, tree); extern tree c_type_promotes_to (tree); +extern tree default_conversion (tree); extern tree composite_type (tree, tree); extern tree build_component_ref (tree, tree); extern tree build_indirect_ref (tree, const char *); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index d5046d5f425..a89c87a3601 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1352,40 +1352,17 @@ default_function_array_conversion (tree exp) return exp; } -/* Perform default promotions for C data used in expressions. - Arrays and functions are converted to pointers; - enumeral types or short or char, to int. - In addition, manifest constants symbols are replaced by their values. */ + +/* EXP is an expression of integer type. Apply the integer promotions + to it and return the promoted value. */ tree -default_conversion (tree exp) +perform_integral_promotions (tree exp) { - tree orig_exp; tree type = TREE_TYPE (exp); enum tree_code code = TREE_CODE (type); - if (code == FUNCTION_TYPE || code == ARRAY_TYPE) - return default_function_array_conversion (exp); - - /* Constants can be used directly unless they're not loadable. */ - if (TREE_CODE (exp) == CONST_DECL) - exp = DECL_INITIAL (exp); - - /* Replace a nonvolatile const static variable with its value unless - it is an array, in which case we must be sure that taking the - address of the array produces consistent results. */ - else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE) - { - exp = decl_constant_value_for_broken_optimization (exp); - type = TREE_TYPE (exp); - } - - /* Strip no-op conversions. */ - orig_exp = exp; - STRIP_TYPE_NOPS (exp); - - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp) = 1; + gcc_assert (INTEGRAL_TYPE_P (type)); /* Normally convert enums to int, but convert wide enums to something wider. */ @@ -1400,6 +1377,8 @@ default_conversion (tree exp) return convert (type, exp); } + /* ??? This should no longer be needed now bit-fields have their + proper types. */ if (TREE_CODE (exp) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)) /* If it's thinner than an int, promote it like a @@ -1418,6 +1397,48 @@ default_conversion (tree exp) return convert (integer_type_node, exp); } + return exp; +} + + +/* Perform default promotions for C data used in expressions. + Arrays and functions are converted to pointers; + enumeral types or short or char, to int. + In addition, manifest constants symbols are replaced by their values. */ + +tree +default_conversion (tree exp) +{ + tree orig_exp; + tree type = TREE_TYPE (exp); + enum tree_code code = TREE_CODE (type); + + if (code == FUNCTION_TYPE || code == ARRAY_TYPE) + return default_function_array_conversion (exp); + + /* Constants can be used directly unless they're not loadable. */ + if (TREE_CODE (exp) == CONST_DECL) + exp = DECL_INITIAL (exp); + + /* Replace a nonvolatile const static variable with its value unless + it is an array, in which case we must be sure that taking the + address of the array produces consistent results. */ + else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE) + { + exp = decl_constant_value_for_broken_optimization (exp); + type = TREE_TYPE (exp); + } + + /* Strip no-op conversions. */ + orig_exp = exp; + STRIP_TYPE_NOPS (exp); + + if (TREE_NO_WARNING (orig_exp)) + TREE_NO_WARNING (exp) = 1; + + if (INTEGRAL_TYPE_P (type)) + return perform_integral_promotions (exp); + if (code == VOID_TYPE) { error ("void value not ignored as it ought to be"); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 237fe33a018..c242a87dd34 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2005-03-23 Joseph S. Myers <joseph@codesourcery.com> + + * cp-tree.h (perform_integral_promotions): Remove. + (default_conversion): Add. + 2005-03-22 Mark Mitchell <mark@codesourcery.com> * parser.c (cp_parser_warn_min_max): New function. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e76e216a065..22e9ee0f8a0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4283,7 +4283,7 @@ extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool); #define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false) extern tree inline_conversion (tree); extern tree decay_conversion (tree); -extern tree perform_integral_promotions (tree); +extern tree default_conversion (tree); extern tree build_class_member_access_expr (tree, tree, tree, bool); extern tree finish_class_member_access_expr (tree, tree); extern tree build_x_indirect_ref (tree, const char *); |