diff mbox series

[Ada] Be more permissive for comparisons with literals in dimension system

Message ID 20171020160546.GA8922@adacore.com
State New
Headers show
Series [Ada] Be more permissive for comparisons with literals in dimension system | expand

Commit Message

Pierre-Marie de Rodat Oct. 20, 2017, 4:05 p.m. UTC
The dimension system in GNAT now allows to compare a dimensioned
expression with a literal, but it issues a warning in this case if the
literal is not zero.

The following code compiles with warnings:

     $ gcc -c use_dims.adb

     1. with System.Dim.Mks; use System.Dim.Mks;
     2.
     3. procedure Use_Dims with SPARK_Mode is
     4.    X : Speed := 0.0;
     5.    Y : Speed := 1.0;
                        |
        >>> warning: assumed to be "1.0 m.s**(-1)"

     6. begin
     7.    if X = 0.0 then
     8.       null;
     9.    elsif 0.0 = X then
    10.       null;
    11.    elsif X = 1.0 then
                     |
        >>> warning: assumed to be "1.0 m.s**(-1)"

    12.       null;
    13.    end if;
    14. end Use_Dims;

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

2017-10-20  Yannick Moy  <moy@adacore.com>

	* sem_dim.adb (Analyze_Dimension_Binary_Op): Accept with a warning to
	compare a dimensioned expression with a literal.
	(Dim_Warning_For_Numeric_Literal): Do not issue a warning for the
	special value zero.
	* doc/gnat_ugn/gnat_and_program_execution.rst: Update description of
	dimensionality system in GNAT.
	* gnat_ugn.texi: Regenerate.
diff mbox series

Patch

Index: doc/gnat_ugn/gnat_and_program_execution.rst
===================================================================
--- doc/gnat_ugn/gnat_and_program_execution.rst	(revision 253938)
+++ doc/gnat_ugn/gnat_and_program_execution.rst	(working copy)
@@ -3611,21 +3611,27 @@ 
 ``Acceleration``.
 
 The dimensionality checks for relationals use the same rules as
-for "+" and "-"; thus
+for "+" and "-", except when comparing to a literal; thus
 
   .. code-block:: ada
 
-        acc > 10.0
+        acc > len
 
 is equivalent to
 
   .. code-block:: ada
 
-       acc-10.0 > 0.0
+       acc-len > 0.0
 
-and is thus illegal. Analogously a conditional expression
-requires the same dimension vector for each branch.
+and is thus illegal, but
 
+  .. code-block:: ada
+
+        acc > 10.0
+
+is accepted with a warning. Analogously a conditional expression requires the
+same dimension vector for each branch (with no exception for literals).
+
 The dimension vector of a type conversion :samp:`T({expr})` is defined
 as follows, based on the nature of ``T``:
 
Index: sem_dim.adb
===================================================================
--- sem_dim.adb	(revision 253941)
+++ sem_dim.adb	(working copy)
@@ -1577,6 +1577,20 @@ 
                   then
                      null;
 
+                  --  Numeric literal case. Issue a warning to indicate the
+                  --  literal is treated as if its dimension matches the type
+                  --  dimension.
+
+                  elsif Nkind_In (Original_Node (L), N_Real_Literal,
+                                                     N_Integer_Literal)
+                  then
+                     Dim_Warning_For_Numeric_Literal (L, Etype (R));
+
+                  elsif Nkind_In (Original_Node (R), N_Real_Literal,
+                                                     N_Integer_Literal)
+                  then
+                     Dim_Warning_For_Numeric_Literal (R, Etype (L));
+
                   else
                      Error_Dim_Msg_For_Binary_Op (N, L, R);
                   end if;
@@ -2724,6 +2738,24 @@ 
 
    procedure Dim_Warning_For_Numeric_Literal (N : Node_Id; Typ : Entity_Id) is
    begin
+      --  Consider the literal zero (integer 0 or real 0.0) to be of any
+      --  dimension.
+
+      case Nkind (Original_Node (N)) is
+         when N_Real_Literal =>
+            if Expr_Value_R (N) = Ureal_0 then
+               return;
+            end if;
+
+         when N_Integer_Literal =>
+            if Expr_Value (N) = Uint_0 then
+               return;
+            end if;
+
+         when others =>
+            null;
+      end case;
+
       --  Initialize name buffer
 
       Name_Len := 0;
Index: gnat_ugn.texi
===================================================================
--- gnat_ugn.texi	(revision 253938)
+++ gnat_ugn.texi	(working copy)
@@ -21,7 +21,7 @@ 
 
 @copying
 @quotation
-GNAT User's Guide for Native Platforms , Oct 14, 2017
+GNAT User's Guide for Native Platforms , Oct 20, 2017
 
 AdaCore
 
@@ -12474,8 +12474,8 @@ 
 This switch activates warnings for exception usage when pragma Restrictions
 (No_Exception_Propagation) is in effect. Warnings are given for implicit or
 explicit exception raises which are not covered by a local handler, and for
-exception handlers which do not cover a local raise. The default is that these
-warnings are not given.
+exception handlers which do not cover a local raise. The default is that
+these warnings are given for units that contain exception handlers.
 
 @item @code{-gnatw.X}
 
@@ -22901,12 +22901,12 @@ 
 @code{Acceleration}.
 
 The dimensionality checks for relationals use the same rules as
-for "+" and "-"; thus
+for "+" and "-", except when comparing to a literal; thus
 
 @quotation
 
 @example
-acc > 10.0
+acc > len
 @end example
 @end quotation
 
@@ -22915,13 +22915,22 @@ 
 @quotation
 
 @example
-acc-10.0 > 0.0
+acc-len > 0.0
 @end example
 @end quotation
 
-and is thus illegal. Analogously a conditional expression
-requires the same dimension vector for each branch.
+and is thus illegal, but
 
+@quotation
+
+@example
+acc > 10.0
+@end example
+@end quotation
+
+is accepted with a warning. Analogously a conditional expression requires the
+same dimension vector for each branch (with no exception for literals).
+
 The dimension vector of a type conversion @code{T(@emph{expr})} is defined
 as follows, based on the nature of @code{T}: