[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Wed, 7 Jan 2015 09:52:50 +0000 (10:52 +0100)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 7 Jan 2015 09:52:50 +0000 (10:52 +0100)
2015-01-07  Tristan Gingold  <gingold@adacore.com>

* i-cpoint.adb (Copy_Terminated_Array): Use Copy_Array to
handle overlap.

2015-01-07  Eric Botcazou  <ebotcazou@adacore.com>

* sem_ch3.adb (Analyze_Full_Type_Declaration): Do not
automatically set No_Strict_Aliasing on access types.
* fe.h (No_Strict_Aliasing_CP): Declare.
* gcc-interface/trans.c (gigi): Force flag_strict_aliasing to 0 if
No_Strict_Aliasing_CP is set.

2015-01-07  Johannes Kanig  <kanig@adacore.com>

* sem_ch8.adb (Analyze_Subprogram_Renaming) do
not build function wrapper in gnatprove mode when the package
is externally axiomatized.

2015-01-07  Jose Ruiz  <ruiz@adacore.com>

* a-reatim.adb (Time_Of): Reduce the number of spurious overflows in
intermediate computations when the parameters have different signs.

2015-01-07  Javier Miranda  <miranda@adacore.com>

* exp_ch3.adb (Build_Init_Procedure): For derived types,
improve the code which takes care of identifying and moving to
the beginning of the init-proc the call to the init-proc of the
parent type.

From-SVN: r219287

gcc/ada/ChangeLog
gcc/ada/a-reatim.adb
gcc/ada/exp_ch3.adb
gcc/ada/fe.h
gcc/ada/gcc-interface/trans.c
gcc/ada/i-cpoint.adb
gcc/ada/sem_ch3.adb
gcc/ada/sem_ch8.adb

index 0965f21f088706f4514650f6893eb59b821af526..3fb4b233c8c86753c21c060c713aa2f98c5cc047 100644 (file)
@@ -1,3 +1,34 @@
+2015-01-07  Tristan Gingold  <gingold@adacore.com>
+
+       * i-cpoint.adb (Copy_Terminated_Array): Use Copy_Array to
+       handle overlap.
+
+2015-01-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * sem_ch3.adb (Analyze_Full_Type_Declaration): Do not
+       automatically set No_Strict_Aliasing on access types.
+       * fe.h (No_Strict_Aliasing_CP): Declare.
+       * gcc-interface/trans.c (gigi): Force flag_strict_aliasing to 0 if
+       No_Strict_Aliasing_CP is set.
+
+2015-01-07  Johannes Kanig  <kanig@adacore.com>
+
+       * sem_ch8.adb (Analyze_Subprogram_Renaming) do
+       not build function wrapper in gnatprove mode when the package
+       is externally axiomatized.
+
+2015-01-07  Jose Ruiz  <ruiz@adacore.com>
+
+       * a-reatim.adb (Time_Of): Reduce the number of spurious overflows in
+       intermediate computations when the parameters have different signs.
+
+2015-01-07  Javier Miranda  <miranda@adacore.com>
+
+       * exp_ch3.adb (Build_Init_Procedure): For derived types,
+       improve the code which takes care of identifying and moving to
+       the beginning of the init-proc the call to the init-proc of the
+       parent type.
+
 2015-01-07  Olivier Hainque  <hainque@adacore.com>
 
        * gcc-interface/trans.c (gnat_to_gnu, <N_Expression_With_Action>):
index f59d083b03c11b3859aeda8908fd883c0cb361b6..1a233c49481a35f17856637b898d5f77040554ae 100644 (file)
@@ -218,7 +218,58 @@ package body Ada.Real_Time is
 
    function Time_Of (SC : Seconds_Count; TS : Time_Span) return Time is
    begin
-      return Time (SC) + TS;
+      --  We want to return Time (SC) + TS. To avoid spurious overflows in
+      --  the intermediate result Time (SC) we take advantage of the different
+      --  signs in SC and TS (when that is the case).
+
+      --  If signs of SC and TS are different then we avoid converting SC to
+      --  Time (as we do in the else part). The reason for that is that SC
+      --  converted to Time may overflow the range of Time, while the addition
+      --  of SC plus TS does not overflow (because of their different signs).
+      --  The approach is to add and remove the greatest value of time
+      --  (greatest absolute value) to both SC and TS. SC and TS have different
+      --  signs, so we add the positive constant to the negative value, and the
+      --  negative constant to the positive value, to prevent overflows.
+
+      if (SC > 0 and then TS < 0.0)
+        or else (SC < 0 and then TS > 0.0)
+      then
+         declare
+            Closest_Boundary : constant Seconds_Count :=
+              (if TS >= 0.0 then
+                  Seconds_Count (Time_Span_Last  - Time_Span (0.5))
+               else
+                  Seconds_Count (Time_Span_First + Time_Span (0.5)));
+            --  Value representing the integer part of the Time_Span boundary
+            --  closest to TS (its number of seconds). Truncate towards zero
+            --  to be sure that transforming this value back into Time cannot
+            --  overflow (when SC is equal to 0). The sign of Closest_Boundary
+            --  is always different from the sign of SC, hence avoiding
+            --  overflow in the expression Time (SC + Closest_Boundary)
+            --  which is part of the return statement.
+
+            Dist_To_Boundary : constant Time_Span :=
+              TS - Time_Span (Closest_Boundary);
+            --  Distance between TS and Closest_Boundary expressed in Time_Span
+            --  Both operands in the substraction have the same sign, hence
+            --  avoiding overflow.
+
+         begin
+            --  Both operands in the inner addition have different signs,
+            --  hence avoiding overflow. The Time () conversion and the outer
+            --  addition can overflow only if SC + TC is not within Time'Range.
+
+            return Time (SC + Closest_Boundary) + Dist_To_Boundary;
+         end;
+
+      --  Both operands have the same sign, so we can convert SC into Time
+      --  right away; if this conversion overflows then the result of adding SC
+      --  and TS would overflow anyway (so we would just be detecting the
+      --  overflow a bit earlier).
+
+      else
+         return Time (SC) + TS;
+      end if;
    end Time_Of;
 
    -----------------
index d45dbddc41bb1925c483afe2e16d44c20b5e896e..74afb6034c6e470a63c73b600b019063a123e96a 100644 (file)
@@ -2391,11 +2391,43 @@ package body Exp_Ch3 is
                   --  such case the initialization of the _parent field was not
                   --  generated.
 
-                  if not Is_Interface (Etype (Rec_Ent))
-                    and then Nkind (First (Stmts)) = N_Procedure_Call_Statement
-                    and then Is_Init_Proc (Name (First (Stmts)))
-                  then
-                     Prepend_To (Body_Stmts, Remove_Head (Stmts));
+                  if not Is_Interface (Etype (Rec_Ent)) then
+                     declare
+                        Parent_IP : constant Name_Id :=
+                                      Make_Init_Proc_Name (Etype (Rec_Ent));
+                        Stmt      : Node_Id := First (Stmts);
+                        IP_Call   : Node_Id := Empty;
+                        IP_Stmts  : List_Id;
+
+                     begin
+                        --  Look for a call to the parent IP at the beginning
+                        --  of Stmts associated with the record extension
+
+                        while Present (Stmt) loop
+                           if Nkind (Stmt) = N_Procedure_Call_Statement
+                             and then Chars (Name (Stmt)) = Parent_IP
+                           then
+                              IP_Call := Stmt;
+                              exit;
+                           end if;
+
+                           Next (Stmt);
+                        end loop;
+
+                        --  If found then move it to the beginning of the
+                        --  statements of this IP routine
+
+                        if Present (IP_Call) then
+                           IP_Stmts := New_List;
+                           loop
+                              Stmt := Remove_Head (Stmts);
+                              Append_To (IP_Stmts, Stmt);
+                              exit when Stmt = IP_Call;
+                           end loop;
+
+                           Prepend_List_To (Body_Stmts, IP_Stmts);
+                        end if;
+                     end;
                   end if;
 
                   Append_List_To (Body_Stmts, Stmts);
index fcd2f153324b008b92ce9653b3202ea769ff5c49..88686e8c44958970ffd8f399f762594a49f4a62d 100644 (file)
@@ -176,6 +176,7 @@ extern Boolean In_Same_Source_Unit              (Node_Id, Node_Id);
 #define Generate_SCO_Instance_Table    opt__generate_sco_instance_table
 #define GNAT_Mode                      opt__gnat_mode
 #define List_Representation_Info       opt__list_representation_info
+#define No_Strict_Aliasing_CP          opt__no_strict_aliasing
 
 typedef enum {Setjmp_Longjmp, Back_End_Exceptions} Exception_Mechanism_Type;
 
@@ -187,6 +188,7 @@ extern Char Float_Format;
 extern Boolean Generate_SCO_Instance_Table;
 extern Boolean GNAT_Mode;
 extern Int List_Representation_Info;
+extern Boolean No_Strict_Aliasing_CP;
 
 /* restrict: */
 
index e77aee0ae7d05ecb210b2b4048922dbcb0372811..a81467067b14da64b0545c5f6242ad0f08cf00db 100644 (file)
@@ -667,6 +667,10 @@ gigi (Node_Id gnat_root,
   /* Initialize the GCC support for FP operations.  */
   gnat_init_gcc_fp ();
 
+  /* Force -fno-strict-aliasing if the configuration pragma was seen.  */
+  if (No_Strict_Aliasing_CP)
+    flag_strict_aliasing = 0;
+
   /* Now translate the compilation unit proper.  */
   Compilation_Unit_to_gnu (gnat_root);
 
index afcb96b9d4ca569ac9441c946f5d1a5018041581..6b3c84d2293288473dcdc72033e10ecaaff242f3 100644 (file)
@@ -143,23 +143,21 @@ package body Interfaces.C.Pointers is
       Limit      : ptrdiff_t := ptrdiff_t'Last;
       Terminator : Element := Default_Terminator)
    is
-      S : Pointer   := Source;
-      T : Pointer   := Target;
-      L : ptrdiff_t := Limit;
-
+      L : ptrdiff_t;
+      S : Pointer := Source;
    begin
-      if S = null or else T = null then
+      if Source = null then
          raise Dereference_Error;
-
-      else
-         while L > 0 loop
-            T.all := S.all;
-            exit when T.all = Terminator;
-            Increment (T);
-            Increment (S);
-            L := L - 1;
-         end loop;
       end if;
+
+      --  Compute array length (including the terminator)
+      L := 1;
+      while S.all /= Terminator and then L < Limit loop
+         L := L + 1;
+         Increment (S);
+      end loop;
+
+      Copy_Array (Source, Target, L);
    end Copy_Terminated_Array;
 
    ---------------
index ac52f08aeb974ba06fa4b122209cf57584ca9971..2850afcdd2b10d90a7790c82ae7588768dd9100d 100644 (file)
@@ -2657,12 +2657,6 @@ package body Sem_Ch3 is
                   Add_RACW_Features (Def_Id);
                end if;
 
-               --  Set no strict aliasing flag if config pragma seen
-
-               if Opt.No_Strict_Aliasing then
-                  Set_No_Strict_Aliasing (Base_Type (Def_Id));
-               end if;
-
             when N_Array_Type_Definition =>
                Array_Type_Declaration (T, Def);
 
index 26b697f3c3a5ef63ced0431bef8b848cde093b5d..2b4f52830e16067f0f022b6ab5fad2586ce382f8 100644 (file)
@@ -2710,7 +2710,17 @@ package body Sem_Ch8 is
          --  Check whether the renaming is for a defaulted actual subprogram
          --  with a class-wide actual.
 
-         if CW_Actual and then Box_Present (Inst_Node) then
+         --  The class-wide wrapper is not needed when we are in
+         --  GNATprove_Mode and there is an external axiomatization on the
+         --  package.
+
+         if CW_Actual
+            and then Box_Present (Inst_Node)
+            and then not (GNATprove_Mode
+                          and then
+                          Present (Containing_Package_With_Ext_Axioms
+                                     (Formal_Spec)))
+         then
             Build_Class_Wide_Wrapper (New_S, Old_S);
 
          elsif Is_Entity_Name (Nam)