This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to start default_conversion cleanup
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Mar 2005 18:08:15 +0000 (UTC)
- Subject: Patch to start default_conversion cleanup
default_conversion for C does about five different things. One of them,
converting arrays to pointers, depending on language-specific information
about whether an array is an lvalue (in C90) which will no longer be
derivable from the tree. Thus this function should not be called from
c-common code. c-common code calls it to handle case labels, but all it
wants there is the integer promotions. This patch changes the function
which C-family front ends need to provide to c-common from
default_conversion to perform_integral_promotions, with associated C and
C++ header changes, creating such a function for C from the relevant parts
of default_conversion. Bootstrapped with no regressions on
x86_64-unknown-linux-gnu. OK to commit?
(The five things are: functions and arrays converting to pointers;
converting CONST_DECLs to their values (which I don't think should ever be
needed for C); broken optimization of const variable references (which is
mostly obsoleted by tree-ssa, but I'm not sure there won't be any cases
where optimizing earlier allows fold to do more and so yields better
results than there would be if all places which do this in the front end
stopped); integer promotions; and giving an error if the expression is of
void type.)
--
Joseph S. Myers http://www.srcf.ucam.org/~jsm28/gcc/
jsm@polyomino.org.uk (personal mail)
joseph@codesourcery.com (CodeSourcery mail)
jsm28@gcc.gnu.org (Bugzilla assignments and CCs)
2005-03-22 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.
cp:
2005-03-22 Joseph S. Myers <joseph@codesourcery.com>
* cp-tree.h (perform_integral_promotions): Remove.
(default_conversion): Add.
diff -rupN GCC.orig/gcc/c-common.c GCC/gcc/c-common.c
--- GCC.orig/gcc/c-common.c 2005-03-21 17:55:02.000000000 +0000
+++ GCC/gcc/c-common.c 2005-03-22 02:01:58.000000000 +0000
@@ -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
&& 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 -rupN GCC.orig/gcc/c-common.h GCC/gcc/c-common.h
--- GCC.orig/gcc/c-common.h 2005-03-21 02:18:50.000000000 +0000
+++ GCC/gcc/c-common.h 2005-03-21 22:22:53.000000000 +0000
@@ -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 -rupN GCC.orig/gcc/c-tree.h GCC/gcc/c-tree.h
--- GCC.orig/gcc/c-tree.h 2005-03-12 22:16:15.000000000 +0000
+++ GCC/gcc/c-tree.h 2005-03-21 22:51:48.000000000 +0000
@@ -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 -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c 2005-03-21 02:18:50.000000000 +0000
+++ GCC/gcc/c-typeck.c 2005-03-21 22:49:16.000000000 +0000
@@ -1352,40 +1352,17 @@ default_function_array_conversion (tree
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 -rupN GCC.orig/gcc/cp/cp-tree.h GCC/gcc/cp/cp-tree.h
--- GCC.orig/gcc/cp/cp-tree.h 2005-03-21 02:18:50.000000000 +0000
+++ GCC/gcc/cp/cp-tree.h 2005-03-21 22:52:08.000000000 +0000
@@ -4283,7 +4283,7 @@ extern tree cxx_sizeof_or_alignof_type
#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 *);