diff mbox

[Ada] Spurious error on case statement with conversion and static predicate

Message ID 20170106111020.GA118900@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Jan. 6, 2017, 11:10 a.m. UTC
This patch fixes a spurious error on a case statement whose expression is a
type conversion of a variable whose initial value is known, and whose type
has a static predicate.

Executing:

   gnatmake -q static_predicate_example
   static_predicate_example
   gnatmake -q -f -gnata static_predicate_example
   static_predicate_example

must yield:

   woof
   woof
   woof
   woof

---
with Ada.Text_Io;

procedure Static_Predicate_Example is

  type Animal_Type is (Bear, Cat, Dog, Horse, Wolf);

  subtype Pet_Type is Animal_Type with Static_Predicate =>
    (case Pet_Type is
       when Cat | Dog | Horse => True,
       when Bear | Wolf       => False);

    My_Animal           : Animal_Type := Dog;
    My_Animal_Converted : Pet_Type    := Pet_Type (My_Animal);
begin
  if My_Animal in Pet_Type then
    case Pet_Type (My_Animal) is
      when Cat   => Ada.Text_Io.Put_Line ("meow");
      when Dog   => Ada.Text_Io.Put_Line ("woof");
      when Horse => Ada.Text_Io.Put_Line ("eeehehe");
    end case;
  end if;

  case My_Animal_Converted is
    when Cat   => Ada.Text_Io.Put_Line ("meow");
    when Dog   => Ada.Text_Io.Put_Line ("woof");
    when Horse => Ada.Text_Io.Put_Line ("eeehehe");
  end case;
end Static_Predicate_Example;

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-01-06  Ed Schonberg  <schonberg@adacore.com>

	* sem_eval.adb (Check_Expression_Against_Static_Predicate):
	If expression is compile-time known and obeys a static predicate
	it must be labelled as static, to prevent spurious warnings and
	run-time errors, e.g. in case statements. This is relevant when
	the expression is the result of constant-folding a type conversion
	whose expression is a variable with a known static value.
diff mbox

Patch

Index: sem_eval.adb
===================================================================
--- sem_eval.adb	(revision 244124)
+++ sem_eval.adb	(working copy)
@@ -347,7 +347,11 @@ 
 
       --  Here we have a static predicate (note that it could have arisen from
       --  an explicitly specified Dynamic_Predicate whose expression met the
-      --  rules for being predicate-static).
+      --  rules for being predicate-static). If the expression is known at
+      --  compile time and obeys the predicate, then it is static and must be
+      --  labeled as such, which matters e.g. for case statements. The original
+      --  expression may be a type conversion of a variable with a known value,
+      --  which might otherwise not be marked static.
 
       --  Case of real static predicate
 
@@ -356,6 +360,7 @@ 
               (Val => Make_Real_Literal (Sloc (Expr), Expr_Value_R (Expr)),
                Typ => Typ)
          then
+            Set_Is_Static_Expression (Expr);
             return;
          end if;
 
@@ -365,6 +370,7 @@ 
          if Real_Or_String_Static_Predicate_Matches
               (Val => Expr_Value_S (Expr), Typ => Typ)
          then
+            Set_Is_Static_Expression (Expr);
             return;
          end if;
 
@@ -376,6 +382,7 @@ 
          --  If static predicate matches, nothing to do
 
          if Choices_Match (Expr, Static_Discrete_Predicate (Typ)) = Match then
+            Set_Is_Static_Expression (Expr);
             return;
          end if;
       end if;