This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Proper handling of dimension information in a type conversion.


This patch implements the proper handling of dimension information on type
conversions. Given a conversion T (Expr), where the expression has type TE,
the following cases arise:

a) If TE has dimension information, the dimensions of the conversion are those
of TE.

b) If TE has no dimension information, dimensions of conversion are those of T.

c) If T and TE belong to different dimension systems, they must have identical
dimensions, unless T is the root type of its system, in which case dimensions
are those of TE, and the conversion can be seen as a "view conversion" that
preserves the dimensions of its argument.

d) If T is a non-dimensioned type, such a Standard.Float, the conversion has no
dimension information.

The following must compile quietly:

   gcc -c  main.adb
   gcc -c -gnatd.F main.adb

---
with Units; use Units;

procedure main with SPARK_Mode is

   subtype Servo_Angle_Type is
       Units.Angle_Type range  -40.0 * Degree .. 40.0 * Degree;

   function Sat_Servo_Angle is new Saturated_Cast (Servo_Angle_Type);
begin
   null;
end main;
---
with Ada.Numerics;

package units with SPARK_Mode is

    type Unit_Type is new Float with  
        Dimension_System =>
        ((Unit_Name => Meter, Unit_Symbol => 'm', Dim_Symbol => 'L'),
         (Unit_Name => Kilogram, Unit_Symbol => "kg", Dim_Symbol => 'M'),
         (Unit_Name => Second, Unit_Symbol => 's', Dim_Symbol => 'T'),
         (Unit_Name => Ampere, Unit_Symbol => 'A', Dim_Symbol => 'I'),
         (Unit_Name => Kelvin, Unit_Symbol => 'K', Dim_Symbol => "Theta"),
         (Unit_Name => Radian, Unit_Symbol => "Rad", Dim_Symbol => "A")),
       Default_Value => 0.0; -- required for matrices

   subtype Angle_Type is Unit_Type with
        Dimension => (Symbol => "Rad", Radian => 1, others => 0);

   Degree : constant Angle_Type := Angle_Type (2.0 * Ada.Numerics.Pi / 360.0);

   generic
      type T is digits <>;
   function Saturated_Cast (val : Float) return T with Inline;
   --  convert a float into a more specific float type, and trim
   --  to the value range
end units;
---
package body units with SPARK_Mode is
   function Saturated_Cast (val : Float) return T is
      ret : T;
   begin
      if val >= Float (T'Last) then
         ret := T'Last;
      elsif val <= Float (T'First) then
         ret := T'First;
      else
         ret := T (val);
      end if;
      return ret;
   end Saturated_Cast;
end units;

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

2017-09-07  Ed Schonberg  <schonberg@adacore.com>

	* sem_dim.adb (Analyze_Dimension_Type_Conversion): New procedure
	to handle properly various cases of type conversions where the
	target type and/or the expression carry dimension information.
	(Dimension_System_Root); If a subtype carries dimension
	information, obtain the source parent type that carries the
	Dimension aspect.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]