tree-switch-conversion (array_value_type): Start by resetting candidate type to it...
authorOlivier Hainque <hainque@adacore.com>
Fri, 10 Mar 2017 11:16:21 +0000 (11:16 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Fri, 10 Mar 2017 11:16:21 +0000 (11:16 +0000)
2017-03-10  Olivier Hainque  <hainque@adacore.com>

* tree-switch-conversion (array_value_type): Start by resetting
candidate type to it's main variant.

testsuite/
* gnat.dg/opt64.adb: New test.
* gnat.dg/opt64_pkg.ads: New helper.
* gnat.dg/opt64_pkg.adb: New helper.

From-SVN: r246024

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt64.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt64_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt64_pkg.ads [new file with mode: 0644]
gcc/tree-switch-conversion.c

index b44a7a57c38195594ea373c1da3e0af432a74e13..5050ca8d822c4c3c6303197ab0c572baa54355e0 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-10  Olivier Hainque  <hainque@adacore.com>
+
+       * tree-switch-conversion (array_value_type): Start by resetting
+       candidate type to it's main variant.
+
 2017-03-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/79909
index bf1c69d7425fee94a866e5b8655195396068450e..b17299b9400a26e8c0be9f792a5a9183cf0a7ba5 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-10  Olivier Hainque  <hainque@adacore.com>
+
+       * gnat.dg/opt64.adb: New test.
+       * gnat.dg/opt64_pkg.ads: New helper.
+       * gnat.dg/opt64_pkg.adb: New helper.
+
 2017-03-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/79909
diff --git a/gcc/testsuite/gnat.dg/opt64.adb b/gcc/testsuite/gnat.dg/opt64.adb
new file mode 100644 (file)
index 0000000..6d287d3
--- /dev/null
@@ -0,0 +1,25 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+-- The issue which prompted the test is a compilation failure. Might
+-- as well verify that the generated code performs as expected.
+
+with opt64_pkg; use opt64_pkg;
+
+procedure opt64 is
+  procedure assert (T : boolean) is
+  begin
+    if not T then
+      raise program_error;
+    end if;
+  end;
+begin
+  Encode (1);
+  assert (last_hash = "1");
+  Encode (2);
+  assert (last_hash = "2");
+  Encode (3);
+  assert (last_hash = "3");
+  Encode (6);
+  assert (last_hash = "?");
+end;
diff --git a/gcc/testsuite/gnat.dg/opt64_pkg.adb b/gcc/testsuite/gnat.dg/opt64_pkg.adb
new file mode 100644 (file)
index 0000000..5235e73
--- /dev/null
@@ -0,0 +1,14 @@
+package body Opt64_PKG is
+   
+   procedure Encode (X : Integer) is
+      result : Hash;
+   begin
+      case X is
+         when 1 => result := "1";
+         when 2 => result := "2";
+         when 3 => result := "3";
+         when others => Result := "?";
+      end case;     
+      Last_Hash := Result;
+   end;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt64_pkg.ads b/gcc/testsuite/gnat.dg/opt64_pkg.ads
new file mode 100644 (file)
index 0000000..e4b09fc
--- /dev/null
@@ -0,0 +1,6 @@
+package Opt64_PKG is
+   type Hash is new string (1 .. 1);   
+   Last_Hash : Hash;
+     
+   procedure Encode (X : Integer);
+end;
index ce1d11dca39f4400ff2438c51d3c081381ad245e..1ccb4bdba1aa0068636481a08399691444269f25 100644 (file)
@@ -935,9 +935,9 @@ constructor_contains_same_values_p (vec<constructor_elt, va_gc> *vec)
   return prev;
 }
 
-/* Return type which should be used for array elements, either TYPE,
-   or for integral type some smaller integral type that can still hold
-   all the constants.  */
+/* Return type which should be used for array elements, either TYPE's
+   main variant or, for integral types, some smaller integral type
+   that can still hold all the constants.  */
 
 static tree
 array_value_type (gswitch *swtch, tree type, int num,
@@ -949,6 +949,13 @@ array_value_type (gswitch *swtch, tree type, int num,
   int sign = 0;
   tree smaller_type;
 
+  /* Types with alignments greater than their size can reach here, e.g. out of
+     SRA.  We couldn't use these as an array component type so get back to the
+     main variant first, which, for our purposes, is fine for other types as
+     well.  */
+
+  type = TYPE_MAIN_VARIANT (type);
+
   if (!INTEGRAL_TYPE_P (type))
     return type;