aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-08-25 20:51:02 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-08-25 20:51:02 +0000
commitd0c5c9b14da834ec8345a4aca53d45334cb5562a (patch)
tree9d83bd3b2e6a19b9638628f3287e9f2071b81783 /gcc
parent700686faf4b0dd347b1dc735569b9fdfaef925d6 (diff)
downloadgcc-d0c5c9b14da834ec8345a4aca53d45334cb5562a.zip
gcc-d0c5c9b14da834ec8345a4aca53d45334cb5562a.tar.gz
gcc-d0c5c9b14da834ec8345a4aca53d45334cb5562a.tar.bz2
re PR middle-end/16693 (Bitwise AND is lost when used within a cast to an enum of the same precision)
PR middle-end/16693 PR tree-optimization/16372 * decl.c (finish_enum): Make the precision of the enumerated type the same width as the underlying integer type. * g++.dg/opt/pr16372-1.C: New test case. * g++.dg/opt/pr16693-1.C: New test case. * g++.dg/opt/pr16693-2.C: New test case. From-SVN: r86576
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c9
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/opt/pr16372-1.C17
-rw-r--r--gcc/testsuite/g++.dg/opt/pr16693-1.C25
-rw-r--r--gcc/testsuite/g++.dg/opt/pr16693-2.C21
6 files changed, 86 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c895d54..ec071ae7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2004-08-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/16693
+ PR tree-optimization/16372
+ * decl.c (finish_enum): Make the precision of the enumerated type
+ the same width as the underlying integer type.
+
2004-08-25 Mark Mitchell <mark@codesourcery.com>
PR c++/17155
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 05db490..dfb5681 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9373,7 +9373,14 @@ finish_enum (tree enumtype)
underlying type in the range bmin to bmax, where bmin and bmax are,
respectively, the smallest and largest values of the smallest bit-
field that can store emin and emax. */
- TYPE_PRECISION (enumtype) = precision;
+
+ /* The middle-end currently assumes that types with TYPE_PRECISION
+ narrower than their underlying type are suitably zero or sign
+ extended to fill their mode. g++ doesn't make these guarantees.
+ Until the middle-end can represent such paradoxical types, we
+ set the TYPE_PRECISON to the width of the underlying type. */
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
+
set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
/* [dcl.enum]
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ec0349e..564e993 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2004-08-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/16693
+ PR tree-optimization/16372
+ * g++.dg/opt/pr16372-1.C: New test case.
+ * g++.dg/opt/pr16693-1.C: New test case.
+ * g++.dg/opt/pr16693-2.C: New test case.
+
2004-08-25 Ziemowit Laski <zlaski@apple.com>
* objc.dg/proto-lossage-4.m: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr16372-1.C b/gcc/testsuite/g++.dg/opt/pr16372-1.C
new file mode 100644
index 0000000..b797e4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr16372-1.C
@@ -0,0 +1,17 @@
+// PR tree-optimization/16372
+// { dg-do run }
+// { dg-options "-O1" }
+
+extern "C" void abort();
+
+enum number {ZERO, ONE, TWO, THREE, FOUR, FIVE};
+
+int main() {
+ number n = FIVE;
+
+ if((n == ONE) || (n == TWO) || (n == THREE)) {
+ abort ();
+ }
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/opt/pr16693-1.C b/gcc/testsuite/g++.dg/opt/pr16693-1.C
new file mode 100644
index 0000000..6b71611
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr16693-1.C
@@ -0,0 +1,25 @@
+// PR middle-end/16693
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort();
+
+unsigned short ret6666(int) {
+ return 0x66;
+}
+
+typedef enum {
+ a = 0x0, b = 0x1, c = 0x2, d = 0x3, e = 0x4, f = 0x5,
+ g = 0x6, h = 0x7, i = 0x8, j = 0x9, k = 0xa, l = 0xb,
+ m = 0xc, n = 0xd, o = 0xe, p = 0xf
+} Test_Enum;
+
+int main(void) {
+ unsigned char r1;
+ r1 = static_cast<Test_Enum>(0xf & ret6666(44));
+
+ if(r1 != 0x6)
+ abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/opt/pr16693-2.C b/gcc/testsuite/g++.dg/opt/pr16693-2.C
new file mode 100644
index 0000000..cb60df6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr16693-2.C
@@ -0,0 +1,21 @@
+// PR middle-end/16693
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort();
+
+char foo()
+{
+ return 0x10;
+}
+
+enum E { e = 0x0f };
+
+int main()
+{
+ char c = (char)(E)(e & foo());
+ if (c != 0)
+ abort();
+ return 0;
+}
+