]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[Ada] Fix evaluation of expressions in inlined code
authorYannick Moy <moy@adacore.com>
Wed, 16 Dec 2020 13:37:22 +0000 (14:37 +0100)
committerPierre-Marie de Rodat <derodat@adacore.com>
Thu, 29 Apr 2021 08:00:48 +0000 (04:00 -0400)
gcc/ada/

* sem_eval.adb (Check_Non_Static_Context_For_Overflow): Apply
compile-time checking for overflows in non-static contexts
including inlined code.
(Eval_Arithmetic_Op): Use the new procedure.
(Eval_Unary_Op, Eval_Op_Expon): Add call to the new procedure.

gcc/ada/sem_eval.adb

index 3ccf3a02cd3e05ee920cc0eb0ac186473ef3bc4d..e3b465067c447b3dcbe184f8ba312475570deb7b 100644 (file)
@@ -142,6 +142,16 @@ package body Sem_Eval is
    -- Local Subprograms --
    -----------------------
 
+   procedure Check_Non_Static_Context_For_Overflow
+     (N      : Node_Id;
+      Stat   : Boolean;
+      Result : Uint);
+   --  For a signed integer type, check non-static overflow in Result when
+   --  Stat is False. This applies also inside inlined code, where the static
+   --  property may be an effect of the inlining, which should not be allowed
+   --  to remove run-time checks (whether during compilation, or even more
+   --  crucially in the special inlining-for-proof in GNATprove mode).
+
    function Choice_Matches
      (Expr   : Node_Id;
       Choice : Node_Id) return Match_Result;
@@ -649,6 +659,34 @@ package body Sem_Eval is
       end if;
    end Check_Non_Static_Context;
 
+   -------------------------------------------
+   -- Check_Non_Static_Context_For_Overflow --
+   -------------------------------------------
+
+   procedure Check_Non_Static_Context_For_Overflow
+     (N      : Node_Id;
+      Stat   : Boolean;
+      Result : Uint)
+   is
+   begin
+      if (not Stat or else In_Inlined_Body)
+        and then Is_Signed_Integer_Type (Etype (N))
+      then
+         declare
+            BT : constant Entity_Id := Base_Type (Etype (N));
+            Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
+            Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
+         begin
+            if Result < Lo or else Result > Hi then
+               Apply_Compile_Time_Constraint_Error
+                 (N, "value not in range of }??",
+                  CE_Overflow_Check_Failed,
+                  Ent => BT);
+            end if;
+         end;
+      end if;
+   end Check_Non_Static_Context_For_Overflow;
+
    ---------------------------------
    -- Check_String_Literal_Length --
    ---------------------------------
@@ -2143,25 +2181,10 @@ package body Sem_Eval is
 
             if Is_Modular_Integer_Type (Ltype) then
                Result := Result mod Modulus (Ltype);
-
-               --  For a signed integer type, check non-static overflow
-
-            elsif (not Stat) and then Is_Signed_Integer_Type (Ltype) then
-               declare
-                  BT : constant Entity_Id := Base_Type (Ltype);
-                  Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
-                  Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
-               begin
-                  if Result < Lo or else Result > Hi then
-                     Apply_Compile_Time_Constraint_Error
-                       (N, "value not in range of }??",
-                        CE_Overflow_Check_Failed,
-                        Ent => BT);
-                     return;
-                  end if;
-               end;
             end if;
 
+            Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
             --  If we get here we can fold the result
 
             Fold_Uint (N, Result, Stat);
@@ -3202,6 +3225,8 @@ package body Sem_Eval is
                      Result := Result mod Modulus (Etype (N));
                   end if;
 
+                  Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
                   Fold_Uint (N, Result, Stat);
                end if;
             end;
@@ -4375,6 +4400,8 @@ package body Sem_Eval is
                Result := abs Rint;
             end if;
 
+            Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
             Fold_Uint (N, Result, Stat);
          end;