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]

[Ada] Avoid doing arithmetics in ENUMERAL_TYPE


For

     [subtype p__T34b is p__enum range b .. c]
      R45b : p__T34b := b;
      R45b := p__T34b'succ(R45b);

Gigi generates an additive expression in an enumeral type:

  R45b = (p__T34b___XDLU_1__2) ((p__enum) R45b + 1);

and this is a no-no for non-standard precisions.


Tested on i586-suse-linux, applied on the mainline and 4.4 branch.


2009-04-22  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/utils2.c (build_binary_op) <PLUS_EXPR>: If operation's
	type is an enumeral or a boolean type, change it to an integer type
	with the same mode and signedness.


2009-04-22  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/enum2.adb: New test.
	* gnat.dg/enum2_pkg.ads: New helper.


-- 
Eric Botcazou
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 146578)
+++ gcc-interface/utils2.c	(working copy)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2008, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2009, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -1010,11 +1010,15 @@ build_binary_op (enum tree_code op_code,
 
     case PLUS_EXPR:
     case MINUS_EXPR:
-      /* Avoid doing arithmetics in BOOLEAN_TYPE like the other compilers.
-	 Contrary to C, Ada doesn't allow arithmetics in Standard.Boolean
-	 but we can generate addition or subtraction for 'Succ and 'Pred.  */
-      if (operation_type && TREE_CODE (operation_type) == BOOLEAN_TYPE)
-	operation_type = left_base_type = right_base_type = integer_type_node;
+      /* Avoid doing arithmetics in ENUMERAL_TYPE or BOOLEAN_TYPE like the
+	 other compilers.  Contrary to C, Ada doesn't allow arithmetics in
+	 these types but can generate addition/subtraction for Succ/Pred.  */
+      if (operation_type
+	  && (TREE_CODE (operation_type) == ENUMERAL_TYPE
+	      || TREE_CODE (operation_type) == BOOLEAN_TYPE))
+	operation_type = left_base_type = right_base_type
+	  = gnat_type_for_mode (TYPE_MODE (operation_type),
+				TYPE_UNSIGNED (operation_type));
 
       /* ... fall through ... */
 
@@ -2199,7 +2203,7 @@ fill_vms_descriptor (tree expr, Entity_I
 	  add_stmt (build3 (COND_EXPR, void_type_node,
 			    build_binary_op (GE_EXPR, long_integer_type_node,
 					     convert (long_integer_type_node,
-						      addr64expr), 
+						      addr64expr),
 					     malloc64low),
 			    build_call_raise (CE_Range_Check_Failed, gnat_actual,
 					      N_Raise_Constraint_Error),
-- { dg-do run }
-- { dg-options "-gnat05 -O2" }

with Enum2_Pkg; use Enum2_Pkg;

procedure Enum2 is
  type Enum is (A, B, C, D);
  Table : array (B .. C, 1 .. 1) of F_String := (others => (others => Null_String));
begin
  Table := (others => (others => Null_String));
end;
with Ada.Finalization; use Ada.Finalization;

package Enum2_Pkg is
  type F_String is new Controlled with record
    Data : access String;
  end record;
  Null_String : constant F_String := (Controlled with Data => null);
end Enum2_Pkg;

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