aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/c-common.c14
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/c-tree.h1
-rw-r--r--gcc/c-typeck.c77
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h2
7 files changed, 77 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fcac50b..8bd9d40 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 a18520d..d4b9d5c 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 64daf34..63dcb10 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 adace27..bbfed6a 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 d5046d5..a89c87a 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 237fe33..c242a87 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 e76e216..22e9ee0 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 *);