From 849d624b4a81f4dc9546e29571c970994dc935ed Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 12 Apr 2009 21:39:39 +0000 Subject: [PATCH] fold-const.c (build_range_check): Properly deal with enumeral and boolean base types. * fold-const.c (build_range_check): Properly deal with enumeral and boolean base types. From-SVN: r145988 --- gcc/ChangeLog | 5 +++++ gcc/fold-const.c | 25 +++++++++++++++---------- gcc/testsuite/ChangeLog | 7 ++++++- gcc/testsuite/gnat.dg/enum1.adb | 17 +++++++++++++++++ gcc/testsuite/gnat.dg/enum1_pkg.ads | 9 +++++++++ 5 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/enum1.adb create mode 100644 gcc/testsuite/gnat.dg/enum1_pkg.ads diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b1a41a99db..22204cb7224 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2009-04-12 Eric Botcazou + + * fold-const.c (build_range_check): Properly deal with enumeral and + boolean base types. + 2009-04-12 Steven Bosscher * doc/invoke.texi (max_gcse_passes): Remove documentation. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index dd2f62d4a4b..bd5e97df4a9 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4671,8 +4671,8 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh, static tree build_range_check (tree type, tree exp, int in_p, tree low, tree high) { - tree etype = TREE_TYPE (exp); - tree value; + tree etype = TREE_TYPE (exp), value; + enum tree_code code; #ifdef HAVE_canonicalize_funcptr_for_compare /* Disable this optimization for function pointer expressions @@ -4756,20 +4756,25 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high) /* Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low). This requires wrap-around arithmetics for the type of the expression. */ - switch (TREE_CODE (etype)) + code = TREE_CODE (etype); + switch (code) { case INTEGER_TYPE: + case ENUMERAL_TYPE: + case BOOLEAN_TYPE: /* There is no requirement that LOW be within the range of ETYPE if the latter is a subtype. It must, however, be within the base type of ETYPE. So be sure we do the subtraction in that type. */ - if (TREE_TYPE (etype)) - etype = TREE_TYPE (etype); - break; + if (code == INTEGER_TYPE && TREE_TYPE (etype)) + { + etype = TREE_TYPE (etype); + /* But not in an enumeral or boolean type though. */ + code = TREE_CODE (etype); + } - case ENUMERAL_TYPE: - case BOOLEAN_TYPE: - etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), - TYPE_UNSIGNED (etype)); + if (code != INTEGER_TYPE) + etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), + TYPE_UNSIGNED (etype)); break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a4452b37566..876431a6b75 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ -009-04-12 Uros Bizjak +2009-04-12 Eric Botcazou + + * gnat.dg/enum1.adb: New test. + * gnat.dg/enum1_pkg.ads: New helper. + +2009-04-12 Uros Bizjak PR target/39740 * gcc.target/alpha/pr39740.c: New test. diff --git a/gcc/testsuite/gnat.dg/enum1.adb b/gcc/testsuite/gnat.dg/enum1.adb new file mode 100644 index 00000000000..f751d24a782 --- /dev/null +++ b/gcc/testsuite/gnat.dg/enum1.adb @@ -0,0 +1,17 @@ +-- { dg-do run } +-- { dg-options "-O2" } + +with Enum1_Pkg; use Enum1_Pkg; + +procedure Enum1 is + + function Cond return Boolean is + begin + return My_N = Two or My_N = Three; + end; + +begin + if Cond then + raise Constraint_Error; + end if; +end; diff --git a/gcc/testsuite/gnat.dg/enum1_pkg.ads b/gcc/testsuite/gnat.dg/enum1_pkg.ads new file mode 100644 index 00000000000..ff090869c42 --- /dev/null +++ b/gcc/testsuite/gnat.dg/enum1_pkg.ads @@ -0,0 +1,9 @@ +package Enum1_Pkg is + + type Enum is (One, Two, Three); + + subtype Sub_Enum is Enum; + + My_N : Sub_Enum := One; + +end Enum1_Pkg; -- 2.30.2