+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
+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
--- /dev/null
+-- { 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;
--- /dev/null
+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;
--- /dev/null
+package Opt64_PKG is
+ type Hash is new string (1 .. 1);
+ Last_Hash : Hash;
+
+ procedure Encode (X : Integer);
+end;
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,
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;