re PR middle-end/16693 (Bitwise AND is lost when used within a cast to an enum of...
authorRoger Sayle <roger@eyesopen.com>
Wed, 25 Aug 2004 20:51:02 +0000 (20:51 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Wed, 25 Aug 2004 20:51:02 +0000 (20:51 +0000)
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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr16372-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/pr16693-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/pr16693-2.C [new file with mode: 0644]

index c895d54698c307caf082b3b392535d948a4b0426..ec071ae745aeba0fce8c4f4a10751e072003d279 100644 (file)
@@ -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
index 05db490cffc64113a5b2a4cc949df7eacc43cdbf..dfb5681932481549af660833d956ba0c20a29596 100644 (file)
@@ -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]
index ec0349e33e7d97904369b86e59c4e8781b2fe93d..564e993132c9520c2d3508bc8e6914e1065718b4 100644 (file)
@@ -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 (file)
index 0000000..b797e4a
--- /dev/null
@@ -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 (file)
index 0000000..6b71611
--- /dev/null
@@ -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 (file)
index 0000000..cb60df6
--- /dev/null
@@ -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;
+}
+