This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 *);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]