[Ada] Crash on transient classwide limited view on RHS of short-circuit

2014-07-16 Thread Arnaud Charlet
This change fixes a compiler crash that would occur in some cases where
an expression involving transient return values of a limited view of a
class-wide interface type occur on the right hand side of a short circuit
operator.

The following compilation must be accepted quietly:

$ gcc -c par-ed.adb
limited with Int2;
package Int1 is
   type Int1 is interface;
   type Ref_Int1 is access Int1'Class;
   type Ref_Int1_List is array (Positive range ) of Ref_Int1;
   function F (This : Int1) return Int2.Int2'Class is abstract;
end Int1;
package Int2 is
   type Int2 is interface;
   function Fullname (This : Int2) return String is abstract;
end Int2;
with Int1;
with Int2;
package Par is end;
package body Par.Ed is

   function Find_Toplevel
 (X : Boolean;
  Tls : Int1.Ref_Int1_List;
  Tl : Int1.Int1'Class)
  return Natural
   is
  Res : Natural := 0;
  use type Int2.Int2'Class;
   begin
  for I in Tls'Range loop
 if X
   and then Tl.F.Fullname = Tls (I).all.F.Fullname
 then
Res := I;
exit;
 end if;
  end loop;
  return Res;
   end Find_Toplevel;
end;
package Par.Ed is

   function Find_Toplevel
 (X : Boolean;
  Tls : Int1.Ref_Int1_List;
  Tl : Int1.Int1'Class)
  return Natural;

end;

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

2014-07-16  Thomas Quinot  qui...@adacore.com

* exp_ch4.adb (Find_Hook_Context): New subprogram, extracted
from Process_Transient_Oject.
* exp_ch4.ads: Ditto.
* exp_ch9.adb (Build_Class_Wide_Master): Insert the _master
declaration as an action on the topmost enclosing expression,
not on a possibly conditional subexpreession.

Index: exp_ch9.adb
===
--- exp_ch9.adb (revision 212640)
+++ exp_ch9.adb (working copy)
@@ -29,6 +29,7 @@
 with Elists;   use Elists;
 with Errout;   use Errout;
 with Exp_Ch3;  use Exp_Ch3;
+with Exp_Ch4;  use Exp_Ch4;
 with Exp_Ch6;  use Exp_Ch6;
 with Exp_Ch11; use Exp_Ch11;
 with Exp_Dbug; use Exp_Dbug;
@@ -1151,7 +1152,6 @@
   then
  declare
 Master_Decl : Node_Id;
-
  begin
 Set_Has_Master_Entity (Master_Scope);
 
@@ -1169,7 +1169,7 @@
   Make_Explicit_Dereference (Loc,
 New_Occurrence_Of (RTE (RE_Current_Master), Loc)));
 
-Insert_Action (Related_Node, Master_Decl);
+Insert_Action (Find_Hook_Context (Related_Node), Master_Decl);
 Analyze (Master_Decl);
 
 --  Mark the containing scope as a task master. Masters associated
Index: exp_ch4.adb
===
--- exp_ch4.adb (revision 212640)
+++ exp_ch4.adb (working copy)
@@ -11390,6 +11390,145 @@
   Adjust_Result_Type (N, Typ);
end Expand_Short_Circuit_Operator;
 
+   ---
+   -- Find_Hook_Context --
+   ---
+
+   function Find_Hook_Context (N : Node_Id) return Node_Id is
+  Par : Node_Id;
+  Top : Node_Id;
+
+  Wrapped_Node : Node_Id;
+  --  Note: if we are in a transient scope, we want to reuse it as
+  --  the context for actions insertion, if possible. But if N is itself
+  --  part of the stored actions for the current transient scope,
+  --  then we need to insert at the appropriate (inner) location in
+  --  the not as an action on Node_To_Be_Wrapped.
+
+  In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
+
+   begin
+  --  When the node is inside a case/if expression, the lifetime of any
+  --  temporary controlled object is extended. Find a suitable insertion
+  --  node by locating the topmost case or if expressions.
+
+  if In_Cond_Expr then
+ Par := N;
+ Top := N;
+ while Present (Par) loop
+if Nkind_In (Original_Node (Par), N_Case_Expression,
+  N_If_Expression)
+then
+   Top := Par;
+
+--  Prevent the search from going too far
+
+elsif Is_Body_Or_Package_Declaration (Par) then
+   exit;
+end if;
+
+Par := Parent (Par);
+ end loop;
+
+ --  The topmost case or if expression is now recovered, but it may
+ --  still not be the correct place to add generated code. Climb to
+ --  find a parent that is part of a declarative or statement list,
+ --  and is not a list of actuals in a call.
+
+ Par := Top;
+ while Present (Par) loop
+if Is_List_Member (Par)
+  and then not Nkind_In (Par, N_Component_Association,
+  N_Discriminant_Association,
+  N_Parameter_Association,
+  N_Pragma_Argument_Association)
+  and then not 

[Ada] Missing finalization of a transient class-wide function result

2014-07-16 Thread Arnaud Charlet
This patch corrects the transient object machinery to treat the renamed result
of a controlled function call as a finalizable transient when the context is an
expression with actions. If this was a different context, the lifetime of the
result would be considered extended and not finalized.


-- Source --


--  types.ads

with Ada.Finalization; use Ada.Finalization;

package Types is
   type Ctrl is new Limited_Controlled with record
  Val : Integer := 0;
   end record;

   function F1 (Obj : Ctrl) return Integer;
   function F2 (Val : Integer) return Ctrl'Class;
   procedure Finalize (Obj : in out Ctrl);

   procedure Test (Flag : Boolean; Obj : Ctrl);
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
   procedure Finalize (Obj : in out Ctrl) is
   begin
  Put_Line (fin  Obj.Val'Img);
   end Finalize;

   function F1 (Obj : Ctrl) return Integer is
   begin
  return Obj.Val + 1;
   end F1;

   function F2 (Val : Integer) return Ctrl'Class is
   begin
  Put_Line (ini  Val'Img);
  return Ctrl'(Limited_Controlled with Val = Val);
   end F2;

   procedure Test (Flag : Boolean; Obj : Ctrl) is
   begin
  if Flag and then F2 (F1 (Obj)).Val = 42 then
 raise Program_Error;
  end if;
   end Test;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;   use Types;

procedure Main is
begin
   declare
  Obj : Ctrl;
   begin
  Obj.Val := 1;
  Test (True, Obj);
   exception
  when others =
 Put_Line (ERROR: unexpected exception 1);
   end;

   declare
  Obj : Ctrl;
   begin
  Obj.Val := 41;
  Test (True, Obj);
  Put_Line (ERROR: exception not raised);
   exception
  when Program_Error =
 null;
  when others =
 Put_Line (ERROR: unexpected exception 2);
   end;
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
ini 2
fin 2
fin 1
ini 42
fin 42
fin 41

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

2014-07-16  Hristian Kirtchev  kirtc...@adacore.com

* exp_ch4.ads, exp_ch4.adb (Find_Hook_Context): Relocated to Exp_Util.
* exp_ch7.adb (Process_Declarations): There is no need to check
that a transient object being hooked is controlled as it would
not have been hooked in the first place.
* exp_ch9.adb Remove with and use clause for Exp_Ch4.
* exp_util.adb (Find_Hook_Context): Relocated from Exp_Ch4.
(Is_Aliased): A renaming of a transient controlled object is
not considered aliasing when it occurs within an expression
with actions.
(Requires_Cleanup_Actions): There is no need to
check that a transient object being hooked is controlled as it
would not have been hooked in the first place.
* exp_util.ads (Find_Hook_Context): Relocated from Exp_Ch4.

Index: exp_ch7.adb
===
--- exp_ch7.adb (revision 212640)
+++ exp_ch7.adb (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1825,8 +1825,6 @@
  and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
  and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
N_Object_Declaration
- and then Is_Finalizable_Transient
-(Status_Flag_Or_Transient_Decl (Obj_Id), Decl)
then
   Processing_Actions (Has_No_Init = True);
 
Index: exp_util.adb
===
--- exp_util.adb(revision 212640)
+++ exp_util.adb(working copy)
@@ -2598,6 +2598,145 @@
   raise Program_Error;
end Find_Protection_Type;
 
+   ---
+   -- Find_Hook_Context --
+   ---
+
+   function Find_Hook_Context (N : Node_Id) return Node_Id is
+  Par : Node_Id;
+  Top : Node_Id;
+
+  Wrapped_Node : Node_Id;
+  --  Note: if we are in a transient scope, we want to reuse it as
+  --  the context for actions insertion, if possible. But if N is itself
+  --  part of the stored actions for the current transient scope,
+  --  then we need to insert at the appropriate (inner) location in
+  --  the not as an action on 

[Ada] Enfore SPARK RM rule 7.1.5(2)

2014-07-16 Thread Arnaud Charlet
This patch modifies the analysis of aspects Abstract_State, Initializes and
Initial_Condition to ensure that they are inserted after pragma SPARK_Mode.
The proper placement allows for SPARK_Mode to be analyzed first and dictate
the mode of the related package.


-- Source --


--  initializes_illegal_2.ads

package Initializes_Illegal_2
  with SPARK_Mode,
   Initializes= (S, X),
   Abstract_State = S
is
   X : Integer;
end Initializes_Illegal_2;


-- Compilation and output --


$ gcc -c initializes_illegal_2.ads
initializes_illegal_2.ads:4:08: aspect Abstract_State cannot come after
  aspect Initializes

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

2014-07-16  Hristian Kirtchev  kirtc...@adacore.com

* sem_ch13.adb (Insert_After_SPARK_Mode): Moved to
the outer level of routine Analyze_Aspect_Specifications. Ensure
that the corresponding pragmas of aspects Initial_Condition and
Initializes are inserted after pragma SPARK_Mode.

Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 212640)
+++ sem_ch13.adb(working copy)
@@ -1158,6 +1158,15 @@
   --  Establish the linkages between an aspect and its corresponding
   --  pragma. Flag Delayed should be set when both constructs are delayed.
 
+  procedure Insert_After_SPARK_Mode
+(Prag: Node_Id;
+ Ins_Nod : Node_Id;
+ Decls   : List_Id);
+  --  Subsidiary to the analysis of aspects Abstract_State, Initializes and
+  --  Initial_Condition. Insert node Prag before node Ins_Nod. If Ins_Nod
+  --  denotes pragma SPARK_Mode, then SPARK_Mode is skipped. Decls is the
+  --  associated declarative list where Prag is to reside.
+
   procedure Insert_Delayed_Pragma (Prag : Node_Id);
   --  Insert a postcondition-like pragma into the tree depending on the
   --  context. Prag must denote one of the following: Pre, Post, Depends,
@@ -1182,6 +1191,37 @@
  Set_Parent(Prag, Asp);
   end Decorate_Aspect_And_Pragma;
 
+  -
+  -- Insert_After_SPARK_Mode --
+  -
+
+  procedure Insert_After_SPARK_Mode
+(Prag: Node_Id;
+ Ins_Nod : Node_Id;
+ Decls   : List_Id)
+  is
+ Decl : Node_Id := Ins_Nod;
+
+  begin
+ --  Skip SPARK_Mode
+
+ if Present (Decl)
+   and then Nkind (Decl) = N_Pragma
+   and then Pragma_Name (Decl) = Name_SPARK_Mode
+ then
+Decl := Next (Decl);
+ end if;
+
+ if Present (Decl) then
+Insert_Before (Decl, Prag);
+
+ --  Aitem acts as the last declaration
+
+ else
+Append_To (Decls, Prag);
+ end if;
+  end Insert_After_SPARK_Mode;
+
   ---
   -- Insert_Delayed_Pragma --
   ---
@@ -2007,51 +2047,10 @@
--  immediately.
 
when Aspect_Abstract_State = Abstract_State : declare
-  procedure Insert_After_SPARK_Mode
-(Ins_Nod : Node_Id;
- Decls   : List_Id);
-  --  Insert Aitem before node Ins_Nod. If Ins_Nod denotes
-  --  pragma SPARK_Mode, then SPARK_Mode is skipped. Decls is
-  --  the associated declarative list where Aitem is to reside.
-
-  -
-  -- Insert_After_SPARK_Mode --
-  -
-
-  procedure Insert_After_SPARK_Mode
-(Ins_Nod : Node_Id;
- Decls   : List_Id)
-  is
- Decl : Node_Id := Ins_Nod;
-
-  begin
- --  Skip SPARK_Mode
-
- if Present (Decl)
-   and then Nkind (Decl) = N_Pragma
-   and then Pragma_Name (Decl) = Name_SPARK_Mode
- then
-Decl := Next (Decl);
- end if;
-
- if Present (Decl) then
-Insert_Before (Decl, Aitem);
-
- --  Aitem acts as the last declaration
-
- else
-Append_To (Decls, Aitem);
- end if;
-  end Insert_After_SPARK_Mode;
-
-  --  Local variables
-
   Context : Node_Id := N;
   Decl: Node_Id;
   Decls   : List_Id;
 
-   --  Start of processing for Abstract_State
-
begin
   --  When aspect Abstract_State appears on a generic package,
   --  it is propageted to the package instance. The context in
@@ -2080,6 

[Ada] Warning match string does not need leading/trailing asterisks

2014-07-16 Thread Arnaud Charlet
The warning message pattern given for pragma Warning_As_Error or
for pragma Warnings no longer requires leading and trailing asterisks.
The match can be anywhere in the string without these characters
as shown in this example, compiled with -gnatwa -gnatld7 -gnatj55

Compiling: warnmatch.adb

 1. pragma Warnings (Off, never read);
 2. pragma Warning_As_Error (useless);
 3. procedure WarnMatch is
 4.A : Integer;
 5.B : Integer;
 6. begin
 7.A := 3;
   |
 error: useless assignment to A, value
never referenced [warning-as-error]

 8. end;

 8 lines: No errors, 1 warning (1 treated as errors)

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

2014-07-16  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document that leading/trailing asterisks are
now implied for the pattern match string for pragma Warnings
and Warning_As_Error.
* sem_prag.adb (Acquire_Warning_Match_String): New procedure.
(Analyze_Pragma, case Warning_As_Error): Call
Acquire_Warning_Match_String.
(Analyze_Pragma, case Warnings): Call Acquire_Warning_Match_String.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 212650)
+++ gnat_rm.texi(working copy)
@@ -7328,7 +7328,8 @@
 
 @noindent
 This pragma signals that the entities whose names are listed are
-deliberately not referenced in the current source unit. This
+deliberately not referenced in the current source unit after the
+occurrence of the pragma. This
 suppresses warnings about the
 entities being unreferenced, and in addition a warning will be
 generated if one of these entities is in fact subsequently referenced in the
@@ -7576,12 +7577,16 @@
 
 The pattern may contain asterisks, which match zero or more characters in
 the message. For example, you can use
-@code{pragma Warning_As_Error (*bits of*unused)} to treat the warning
+@code{pragma Warning_As_Error (bits of*unused)} to treat the warning
 message @code{warning: 960 bits of a unused} as an error. No other regular
 expression notations are permitted. All characters other than asterisk in
 these three specific cases are treated as literal characters in the match.
 The match is case insensitive, for example XYZ matches xyz.
 
+Note that the pattern matches if it occurs anywhere within the warning
+message string (it is not necessary to put an asterisk at the start and
+the end of the message, since this is implied).
+
 Another possibility for the static_string_EXPRESSION which works whether
 or not error tags are enabled (@option{-gnatw.d}) is to use the
 @option{-gnatw} tag string, enclosed in brackets,
@@ -7716,20 +7721,24 @@
 
 The pattern may contain asterisks, which match zero or more characters in
 the message. For example, you can use
-@code{pragma Warnings (Off, *bits of*unused)} to suppress the warning
+@code{pragma Warnings (Off, bits of*unused)} to suppress the warning
 message @code{warning: 960 bits of a unused}. No other regular
 expression notations are permitted. All characters other than asterisk in
 these three specific cases are treated as literal characters in the match.
 The match is case insensitive, for example XYZ matches xyz.
 
+Note that the pattern matches if it occurs anywhere within the warning
+message string (it is not necessary to put an asterisk at the start and
+the end of the message, since this is implied).
+
 The above use of patterns to match the message applies only to warning
 messages generated by the front end. This form of the pragma with a string
 argument can also be used to control warnings provided by the back end and
 mentioned above. By using a single full @option{-Wxxx} switch in the pragma,
 such warnings can be turned on and off.
 
-There are two ways to use the pragma in this form. The OFF form can be used as 
a
-configuration pragma. The effect is to suppress all warnings (if any)
+There are two ways to use the pragma in this form. The OFF form can be used
+as a configuration pragma. The effect is to suppress all warnings (if any)
 that match the pattern string throughout the compilation (or match the
 -W switch in the back end case).
 
Index: sem_prag.adb
===
--- sem_prag.adb(revision 212649)
+++ sem_prag.adb(working copy)
@@ -2781,6 +2781,16 @@
   type Args_List is array (Natural range ) of Node_Id;
   --  Types used for arguments to Check_Arg_Order and Gather_Associations
 
+  ---
+  -- Local Subprograms --
+  ---
+
+  procedure Acquire_Warning_Match_String (Arg : Node_Id);
+  --  Used by pragma Warnings (Off, string), and Warn_As_Error (string) to
+  --  get the given string argument, and place it in Name_Buffer, adding
+  --  leading and trailing asterisks if they are not already present. The
+  --  caller has 

[Ada] Catch newly illegal case of Unrestricted_Access

2014-07-16 Thread Arnaud Charlet
It is now illegal to use Unrestricted_Access to directly generate a
thin pointer of an unconstrained array type which references a non-
aliased object. This never worked, and we might as well catch it as
illegal, since it is not hard to do so, as shown in the following
example:

 1. with System; use System;
 2. procedure SliceUA2 is
 3.type A is access all String;
 4.for A'Size use Standard'Address_Size;
 5.
 6.procedure P (Arg : A) is
 7.begin
 8.   null;
 9.end P;
10.
11.X : String := hello world!;
12.X2 : aliased String := hello world!;
13.
14.AV : A := X'Unrestricted_Access;-- ERROR
 |
 illegal use of Unrestricted_Access attribute
 attempt to generate thin pointer to unaliased object

15.
16. begin
17.P (X'Unrestricted_Access);  -- ERROR
  |
 illegal use of Unrestricted_Access attribute
 attempt to generate thin pointer to unaliased object

18.P (X(7 .. 12)'Unrestricted_Access); -- ERROR
  |
 illegal use of Unrestricted_Access attribute
 attempt to generate thin pointer to unaliased object

19.P (X2'Unrestricted_Access); -- OK
20. end;

However we can't catch all cases, so some cases just remain erroneous:

 1. with System; use System;
 2. procedure SliceUA is
 3.type AF is access all String;
 4.
 5.type A is access all String;
 6.for A'Size use Standard'Address_Size;
 7.
 8.procedure P (Arg : A) is
 9.begin
10.   if Arg'Length /= 6 then
11.  raise Program_Error;
12.   end if;
13.end P;
14.
15.X : String := hello world!;
16.Y : AF := X (7 .. 12)'Unrestricted_Access;
17.
18. begin
19.P (A (Y));
20. end;

Here the conversion in the call on line 19 from a fat pointer to a
thin pointer is erroneous, and executing this program inevitably
raises Program_Error since the bounds get lost in the conversion.

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

2014-07-16  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document illegal case of Unrestricted_Access.
* sem_attr.adb (Analyze_Access_Attribute): Set_Non_Aliased_Prefix
where it applies.
(Resolve_Attribute, case Access): Flag illegal Unrestricted_Access use.
* sinfo.ads, sinfo.adb (Non_Aliased_Prefix): New flag.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 212654)
+++ gnat_rm.texi(working copy)
@@ -9551,22 +9551,65 @@
 
 It is possible to use @code{Unrestricted_Access} for any type, but care
 must be exercised if it is used to create pointers to unconstrained array
-objects. In this case, the resulting pointer has the same scope as the
+objects.  In this case, the resulting pointer has the same scope as the
 context of the attribute, and may not be returned to some enclosing
-scope. For instance, a function cannot use @code{Unrestricted_Access}
+scope.  For instance, a function cannot use @code{Unrestricted_Access}
 to create a unconstrained pointer and then return that value to the
-caller. In addition, it is only valid to create pointers to unconstrained
+caller.  In addition, it is only valid to create pointers to unconstrained
 arrays using this attribute if the pointer has the normal default ``fat''
 representation where a pointer has two components, one points to the array
-and one points to the bounds. If a size clause is used to force ``thin''
+and one points to the bounds.  If a size clause is used to force ``thin''
 representation for a pointer to unconstrained where there is only space for
-a single pointer, then any use of @code{Unrestricted_Access}
-to create a value of such a type (e.g. by conversion from fat to
-thin pointers) is erroneous. Consider the following example:
+a single pointer, then the resulting pointer is not usable.
 
+In the simple case where a direct use of Unrestricted_Access attempts
+to make a thin pointer for a non-aliased object, the compiler will
+reject the use as illegal, as shown in the following example:
+
 @smallexample @c ada
 with System; use System;
+procedure SliceUA2 is
+   type A is access all String;
+   for A'Size use Standard'Address_Size;
+
+   procedure P (Arg : A) is
+   begin
+  null;
+   end P;
+
+   X : String := hello world!;
+   X2 : aliased String := hello world!;
+
+   AV : A := X'Unrestricted_Access;-- ERROR
+ |
+ illegal use of Unrestricted_Access attribute
+ attempt to generate thin pointer to unaliased object
+
+begin
+   P (X'Unrestricted_Access);  -- ERROR
+  |
+ illegal use of Unrestricted_Access attribute
+ attempt to generate thin pointer to unaliased object
+
+   P (X(7 .. 12)'Unrestricted_Access); -- ERROR
+  |
+ illegal use of Unrestricted_Access attribute

[Ada] Warning if record size is not a multiple of alignment

2014-07-16 Thread Arnaud Charlet
This implements a new warning (on by default, controlled
by -gnatw.z/-gnatw.Z, included in -gnatwa), that warns
if a record type has a specified size and alignment where
the size is not a multiple of the alignment resulting in
an object size greater than the specified size.

The warning is suppressed if an explicit value is given
for the object size.

THe following test:

 1. package SizeAlign is
 2.type R1 is record
 3.   A,B,C,D,E : Integer;
 4.end record;
 5.for R1'Size use 5*32;
 6.for R1'Alignment use 8;
   |
 warning: size is not a multiple of alignment for R1
 warning: size of 160 specified at line 5
 warning: Object_Size will be increased to 192

 7.
 8.type R2 is record
 9.   A,B,C,D,E : Integer;
10.end record;
11.for R2'Alignment use 8;
12.for R2'Size use 5*32;
   |
 warning: size is not a multiple of alignment for R2
 warning: alignment of 8 specified at line 11
 warning: Object_Size will be increased to 192

13.
14.type R3 is record
15.   A,B,C,D,E : Integer;
16.end record;
17.for R3'Alignment use 8;
18.for R3'Size use 5*32;
19.for R3'Object_Size use 192;
20. end;

generates the given warnings, with the -gnatR2 output of:

Representation information for unit Sizealign (spec)

for R1'Object_Size use 192;
for R1'Value_Size use 160;
for R1'Alignment use 8;
for R1 use record
   A at  0 range  0 .. 31;
   B at  4 range  0 .. 31;
   C at  8 range  0 .. 31;
   D at 12 range  0 .. 31;
   E at 16 range  0 .. 31;
end record;

for R2'Object_Size use 192;
for R2'Value_Size use 160;
for R2'Alignment use 8;
for R2 use record
   A at  0 range  0 .. 31;
   B at  4 range  0 .. 31;
   C at  8 range  0 .. 31;
   D at 12 range  0 .. 31;
   E at 16 range  0 .. 31;
end record;

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

2014-07-16  Robert Dewar  de...@adacore.com

* freeze.adb (Freeze_Entity): Warn on incompatible size/alignment.
* gnat_ugn.texi: Document -gnatw.z and -gnatw.Z.
* ug_words: VMS synonyms (WARNINGS=[NO]SIZE_ALIGN) for -gnatw.z/-gnatw.Z
* usage.adb: Add lines for -gnatw.z/-gnatw.Z.
* vms_data.ads: VMS synonyms (WARNINGS=[NO]SIZE_ALIGN) for
-gnatw.z/-gnatw.Z
* warnsw.adb: Set Warn_On_Size_Alignment appropriately.
* warnsw.ads (Warn_On_Size_Alignment): New flag Minor
reformatting.

Index: usage.adb
===
--- usage.adb   (revision 212640)
+++ usage.adb   (working copy)
@@ -503,7 +503,7 @@
Write_Line (F*   turn off warnings for unreferenced formal);
Write_Line (g*+  turn on warnings for unrecognized pragma);
Write_Line (Gturn off warnings for unrecognized pragma);
-   Write_Line (.g   turn on GNAT warnings, same as Aao.sI.C.V.X);
+   Write_Line (.g   turn on GNAT warnings);
Write_Line (hturn on warnings for hiding declarations);
Write_Line (H*   turn off warnings for hiding declarations);
Write_Line (.h   turn on warnings for holes in records);
@@ -589,6 +589,10 @@
   unchecked conversion);
Write_Line (Zturn off warnings for suspicious  
   unchecked conversion);
+   Write_Line (.z*+ turn on warnings for record size not a  
+  multiple of alignment);
+   Write_Line (.Z   turn off warnings for record size not a  
+  multiple of alignment);
 
--  Line for -gnatW switch
 
Index: ug_words
===
--- ug_words(revision 212640)
+++ ug_words(working copy)
@@ -226,6 +226,8 @@
 -gnatw.Y^ /WARNINGS=NOWHY_SPEC_NEEDS_BODY
 -gnatwz ^ /WARNINGS=UNCHECKED_CONVERSIONS
 -gnatwZ ^ /WARNINGS=NOUNCHECKED_CONVERSIONS
+-gnatw.z^ /WARNINGS=SIZE_ALIGN
+-gnatw.Z^ /WARNINGS=NOSIZE_ALIGN
 -gnatW8 ^ /WIDE_CHARACTER_ENCODING=UTF8
 -gnatW? ^ /WIDE_CHARACTER_ENCODING=?
 -gnaty  ^ /STYLE_CHECKS
Index: gnat_ugn.texi
===
--- gnat_ugn.texi   (revision 212654)
+++ gnat_ugn.texi   (working copy)
@@ -4798,6 +4798,9 @@
 Possible order of elaboration problems
 
 @item
+Size not a multiple of alignment for a record type
+
+@item
 Assertions (pragma Assert) that are sure to fail
 
 @item
@@ -5869,6 +5872,28 @@
 where the types are known at compile time to have different
 sizes or conventions.
 
+@item -gnatw.z
+@emph{Activate warnings for size not a multiple of alignment.}
+@cindex @option{-gnatw.z} (@command{gcc})
+@cindex Size/Alignment warnings
+This switch activates warnings for 

[Ada] A static predicate can be specified by a Case expression.

2014-07-16 Thread Arnaud Charlet
This patch completes the implementation of Ada 2012 static predicates, by
adding support for case expressions that can be transformed into a statically
evaluable expression on values of the subtype. Compiling:

gcc -c -gnata test_predicate.adb

must yield:

test_predicate.adb:11:20:
 warning: static expression fails static predicate check on Weekend
test_predicate.adb:19:25:
 warning: static expression fails static predicate check on French_School

---
with Text_IO; use Text_IO;
procedure Test_Predicate is

type Days is (Sun, Mon, Tue, Wed, Thu, Fri, Sat);

subtype Weekend is Days with Static_Predicate =
  (case Weekend is
 when Sat | Sun = True,
 when Mon .. Fri = False);

W : Weekend := Tue;
subtype French_School is Days with Static_Predicate =
  (case French_School is
 when Mon  | Tue = True,
 when Wed = False,
 when Thu..Fri = True,
 when Sat | Sun = False);
 
   J : French_School := Wed;
begin
Put_Line (W'Img);
end Test_Predicate;

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

2014-07-16  Ed Schonberg  schonb...@adacore.com

* exp_ch4.adb (Expand_N_Case_Expression): Do not expand case
expression if it is the specification of a subtype predicate:
it will be expanded when the return statement is analyzed, or
when a static predicate is transformed into a static expression
for evaluation by the front-end.
* sem_ch13.adb (Get_RList): If the expression for a static
predicate is a case expression, extract the alternatives of the
branches with a True value to create the required statically
evaluable expression.

Index: exp_ch4.adb
===
--- exp_ch4.adb (revision 212648)
+++ exp_ch4.adb (working copy)
@@ -4927,6 +4927,16 @@
  return;
   end if;
 
+  --  If the case expression is a predicate specification, do not
+  --  expand, because it will be converted to the proper predicate
+  --  form when building the predicate function.
+
+  if Ekind_In (Current_Scope, E_Function, E_Procedure)
+and then Is_Predicate_Function (Current_Scope)
+  then
+ return;
+  end if;
+
   --  We expand
 
   --case X is when A = AX, when B = BX ...
Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 212656)
+++ sem_ch13.adb(working copy)
@@ -7584,12 +7584,47 @@
 when N_Qualified_Expression =
return Get_RList (Expression (Exp));
 
+when N_Case_Expression =
+declare
+   Alt : Node_Id;
+   Choices : List_Id;
+   Dep : Node_Id;
+
+begin
+   if not Is_Entity_Name (Expression (Expr))
+ or else Etype (Expression (Expr)) /= Typ
+   then
+  Error_Msg_N
+(expression must denaote subtype, Expression (Expr));
+  return False_Range;
+   end if;
+
+   --  Collect discrete choices in all True alternatives
+
+   Choices := New_List;
+   Alt := First (Alternatives (Exp));
+   while Present (Alt) loop
+  Dep := Expression (Alt);
+
+  if not Is_Static_Expression (Dep) then
+ raise Non_Static;
+
+  elsif Is_True (Expr_Value (Dep)) then
+ Append_List_To (Choices,
+   New_Copy_List (Discrete_Choices (Alt)));
+  end if;
+
+  Next (Alt);
+   end loop;
+
+   return Membership_Entries (First (Choices));
+end;
+
 --  Expression with actions: if no actions, dig out expression
 
 when N_Expression_With_Actions =
if Is_Empty_List (Actions (Exp)) then
   return Get_RList (Expression (Exp));
-
else
   raise Non_Static;
end if;


[Ada] New node kind N_Compound_Statement

2014-07-16 Thread Arnaud Charlet
This change reorganizes expansion of object initialization statements, which
need to be captured under a single node id. Previously these were represented
as a (malformed) N_Expression_With_Actions with a NULL statement as its
expression. This irregularity is fixed by instead introducing a separate
N_Compound_Statement node kind.

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

2014-07-16  Thomas Quinot  qui...@adacore.com

* sinfo.ads, sinfo.adb (N_Compound_Statement): New node kind.
* sem.adb (Analyze): Handle N_Compound_Statement.
* sprint.adb (Sprint_Node_Actual): Ditto.
* cprint.adb (Cprint_Node): Ditto.
* sem_ch5.ads, sem_ch5.adb (Analyze_Compound_Statement): New
procedure to handle N_Compound_Statement.
* exp_aggr.adb (Collect_Initialization_Statements):
Use a proper compound statement node, instead of a bogus
expression-with-actions with a NULL statement as its expression,
to wrap collected initialization statements.
* freeze.ads, freeze.adb
(Explode_Initialization_Compound_Statement): New public procedure,
lifted from Freeze_Entity.
(Freeze_Entity): When freezing
an object with captured initialization statements and without
delayed freezing, explode compount statement.
* sem_ch4.adb (Analyze_Expression_With_Actions): Remove special
case that used to handle bogus EWAs with NULL statement as
the expression.
* exp_ch13.adb (Expand_N_Freeze_Entity): For an object with
delayed freezing and captured initialization statements, explode
compound statement.

Index: sem_ch5.adb
===
--- sem_ch5.adb (revision 212640)
+++ sem_ch5.adb (working copy)
@@ -1016,6 +1016,15 @@
   end;
end Analyze_Block_Statement;
 
+   
+   -- Analyze_Compound_Statement --
+   
+
+   procedure Analyze_Compound_Statement (N : Node_Id) is
+   begin
+  Analyze_List (Actions (N));
+   end Analyze_Compound_Statement;
+

-- Analyze_Case_Statement --

Index: sem_ch5.ads
===
--- sem_ch5.ads (revision 212640)
+++ sem_ch5.ads (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- S p e c  --
 --  --
---  Copyright (C) 1992-2012, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -30,6 +30,7 @@
procedure Analyze_Assignment   (N : Node_Id);
procedure Analyze_Block_Statement  (N : Node_Id);
procedure Analyze_Case_Statement   (N : Node_Id);
+   procedure Analyze_Compound_Statement   (N : Node_Id);
procedure Analyze_Exit_Statement   (N : Node_Id);
procedure Analyze_Goto_Statement   (N : Node_Id);
procedure Analyze_If_Statement (N : Node_Id);
Index: sinfo.adb
===
--- sinfo.adb   (revision 212655)
+++ sinfo.adb   (working copy)
@@ -148,6 +148,7 @@
 or else NT (N).Nkind = N_And_Then
 or else NT (N).Nkind = N_Case_Expression_Alternative
 or else NT (N).Nkind = N_Compilation_Unit_Aux
+or else NT (N).Nkind = N_Compound_Statement
 or else NT (N).Nkind = N_Expression_With_Actions
 or else NT (N).Nkind = N_Freeze_Entity
 or else NT (N).Nkind = N_Or_Else);
@@ -3314,6 +3315,7 @@
 or else NT (N).Nkind = N_And_Then
 or else NT (N).Nkind = N_Case_Expression_Alternative
 or else NT (N).Nkind = N_Compilation_Unit_Aux
+or else NT (N).Nkind = N_Compound_Statement
 or else NT (N).Nkind = N_Expression_With_Actions
 or else NT (N).Nkind = N_Freeze_Entity
 or else NT (N).Nkind = N_Or_Else);
Index: sinfo.ads
===
--- sinfo.ads   (revision 212655)
+++ sinfo.ads   (working copy)
@@ -86,6 +86,7 @@
--Add it to the documentation in the appropriate place
--Add its fields to this documentation section
--Define it in the appropriate classification in Node_Kind
+   --Add an entry in Is_Syntactic_Field
--In the body (sinfo), add entries to the access functions for all
-- its fields (except standard expression fields) to include the new
-- 

[Ada] No usage for an erroneous invocation of a gnat tool

2014-07-17 Thread Arnaud Charlet
When a gnat tool (gnatbind, gnatclean, gnatchop, gnatfind, gnatls,
gnatname, gnatprep or gnatmake) is incorrectly invoked, the usage is
no longer displayed. Instead, this line is displayed:

  type gnatxxx --help for help

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

2014-07-17  Vincent Celier  cel...@adacore.com

* gnatchop.adb, make.adb, gnatbind.adb, clean.adb, gprep.adb,
gnatxref.adb, gnatls.adb, gnatfind.adb, gnatname.adb: Do not output
the usage for an erroneous invocation of a gnat tool.

Index: gnatchop.adb
===
--- gnatchop.adb(revision 212640)
+++ gnatchop.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1998-2012, Free Software Foundation, Inc. --
+--  Copyright (C) 1998-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1248,7 +1248,12 @@
   --  At least one filename must be given
 
   elsif File.Last = 0 then
- Usage;
+ if Argument_Count = 0 then
+Usage;
+ else
+Put_Line (type gnatchop --help for help);
+ end if;
+
  return False;
 
   --  No directory given, set directory to null, so that we can just
Index: make.adb
===
--- make.adb(revision 212659)
+++ make.adb(working copy)
@@ -5856,9 +5856,14 @@
 
 Targparm.Get_Target_Parameters;
 
---  Output usage information if no files to compile
+--  Output usage information if no argument on the command line
 
-Usage;
+if Argument_Count = 0 then
+   Usage;
+else
+   Write_Line (type gnatmake --help for help);
+end if;
+
 Finish_Program (Project_Tree, E_Success);
  end if;
   end if;
Index: gnatbind.adb
===
--- gnatbind.adb(revision 212654)
+++ gnatbind.adb(working copy)
@@ -666,10 +666,15 @@
   Display_Version (GNATBIND, 1995);
end if;
 
-   --  Output usage information if no files
+   --  Output usage information if no arguments
 
if not More_Lib_Files then
-  Bindusg.Display;
+  if Argument_Count = 0 then
+ Bindusg.Display;
+  else
+ Write_Line (type gnatbind --help for help);
+  end if;
+
   Exit_Program (E_Fatal);
end if;
 
Index: clean.adb
===
--- clean.adb   (revision 212640)
+++ clean.adb   (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 2003-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 2003-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1460,11 +1460,16 @@
  end;
   end if;
 
-  --  If neither a project file nor an executable were specified, output
-  --  the usage and exit.
+  --  If neither a project file nor an executable were specified, exit
+  --  displaying the usage if there were no arguments on the command line.
 
   if Main_Project = No_Project and then Osint.Number_Of_Files = 0 then
- Usage;
+ if Argument_Count = 0 then
+Usage;
+ else
+Put_Line (type gnatclean --help for help);
+ end if;
+
  return;
   end if;
 
Index: gprep.adb
===
--- gprep.adb   (revision 212640)
+++ gprep.adb   (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 2002-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 2002-2014, Free Software Foundation, Inc. --
 --  --
 

[Ada] Secondary stack leak for call returning limited discriminated object

2014-07-17 Thread Arnaud Charlet
This change fixes a defect whereby GNAT would fail to generate secondary
stack cleanup code for a scope containing a local object of a limited
discriminated type initialized by a (build-in-place) function call,
thus causing a storage leak.

The following test case must not leak memory for each iteration of the loop:

package Limited_Factory is
   type Lim (D : Integer) is limited private;
   function Create_In_Place return Lim;
private
   type Lim (D : Integer) is limited record
  S : String (1 .. 1024);
   end record;
end Limited_Factory;
package body Limited_Factory is
   function Create_In_Place return Lim is
   begin
  return Lim'(D = 42, S = (others = 'x'));
   end;
end Limited_Factory;
with Limited_Factory; use Limited_Factory;
procedure Sec_Stack_BIP is
   procedure Leak is
  Obj : Lim := Create_In_Place;
   begin
  null;
   end;
begin
   for J in 1 .. 1000 loop
  Leak;
   end loop;
end;

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

2014-07-17  Thomas Quinot  qui...@adacore.com

* exp_ch7.adb (Establish_Transient_Scope.Find_Node_To_Be_Wrapped):
Start examining the tree at the node passed to
Establish_Transient_Scope (not its parent).
* exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration):
The access type for the variable storing the reference to
the call must be declared and frozen prior to establishing a
transient scope.

Index: exp_ch7.adb
===
--- exp_ch7.adb (revision 212716)
+++ exp_ch7.adb (working copy)
@@ -4208,11 +4208,8 @@
 
begin
   The_Parent := N;
+  P  := Empty;
   loop
- P := The_Parent;
- pragma Assert (P /= Empty);
- The_Parent := Parent (P);
-
  case Nkind (The_Parent) is
 
 --  Simple statement can be wrapped
@@ -4263,7 +4260,7 @@
 
 --  The expression itself is to be wrapped if its parent is a
 --  compound statement or any other statement where the expression
---  is known to be scalar
+--  is known to be scalar.
 
 when N_Accept_Alternative   |
  N_Attribute_Definition_Clause  |
@@ -4279,6 +4276,7 @@
  N_If_Statement |
  N_Iteration_Scheme |
  N_Terminate_Alternative=
+   pragma Assert (Present (P));
return P;
 
 when N_Attribute_Reference =
@@ -4344,6 +4342,9 @@
 when others =
null;
  end case;
+
+ P  := The_Parent;
+ The_Parent := Parent (P);
   end loop;
end Find_Node_To_Be_Wrapped;
 
Index: exp_ch6.adb
===
--- exp_ch6.adb (revision 212657)
+++ exp_ch6.adb (working copy)
@@ -10181,10 +10181,9 @@
   Func_Call   : Node_Id := Function_Call;
   Function_Id : Entity_Id;
   Pool_Actual : Node_Id;
+  Ptr_Typ : Entity_Id;
   Ptr_Typ_Decl: Node_Id;
   Pass_Caller_Acc : Boolean := False;
-  New_Expr: Node_Id;
-  Ref_Type: Entity_Id;
   Res_Decl: Node_Id;
   Result_Subt : Entity_Id;
 
@@ -10224,6 +10223,53 @@
 
   Result_Subt := Etype (Function_Id);
 
+  --  Create an access type designating the function's result subtype. We
+  --  use the type of the original call because it may be a call to an
+  --  inherited operation, which the expansion has replaced with the parent
+  --  operation that yields the parent type. Note that this access type
+  --  must be declared before we establish a transient scope, so that it
+  --  receives the proper accessibility level.
+
+  Ptr_Typ := Make_Temporary (Loc, 'A');
+  Ptr_Typ_Decl :=
+Make_Full_Type_Declaration (Loc,
+  Defining_Identifier = Ptr_Typ,
+  Type_Definition =
+Make_Access_To_Object_Definition (Loc,
+  All_Present= True,
+  Subtype_Indication =
+New_Occurrence_Of (Etype (Function_Call), Loc)));
+
+  --  The access type and its accompanying object must be inserted after
+  --  the object declaration in the constrained case, so that the function
+  --  call can be passed access to the object. In the unconstrained case,
+  --  or if the object declaration is for a return object, the access type
+  --  and object must be inserted before the object, since the object
+  --  declaration is rewritten to be a renaming of a dereference of the
+  --  access object. Note: we need to freeze Ptr_Typ explicitly, because
+  --  the result object is in a different (transient) scope, so won't
+  --  cause freezing.
+
+  if Is_Constrained (Underlying_Type (Result_Subt))
+and then not Is_Return_Object (Defining_Identifier 

[Ada] Incomplete detection of external tag clash

2014-07-17 Thread Arnaud Charlet
This change fixes the circuitry responsible for enforcing the uniqueness
of 'External_Tag attribute values. Previously uniqueness was checked at
type elaboration time only for types that have an explicit External_Tag
attribute definition clause. However we must also account for the fact
that the default external tag for a type without any such clause may clash
with that of a type with an explicit clause that has been elaborated
previously.

The elaboration of the following unit must cause PROGRAM_ERROR to be raised:

$ gnatmake -z -gnatws default_explicit_ext_tag.ads
$ ./default_explicit_ext_tag

raised PROGRAM_ERROR : duplicated external tag DEFAULT_EXPLICIT_EXT_TAG.T2

package Default_Explicit_Ext_Tag is
   type T1 is tagged null record;
   for T1'External_Tag use DEFAULT_EXPLICIT_EXT_TAG.T2;

   type T2 is tagged null record;
end Default_Explicit_Ext_Tag;

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

2014-07-17  Thomas Quinot  qui...@adacore.com

* exp_disp.adb (Make_DT, Make_VM_TSD): Do not omit Check_TSD
call for types that do not have an explicit attribute definition
clause for External_Tag, as their default tag may clash with an
explicit tag defined for some other type.

Index: exp_disp.adb
===
--- exp_disp.adb(revision 212640)
+++ exp_disp.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -6209,9 +6209,8 @@
  end if;
   end if;
 
-  --  If the type has a representation clause which specifies its external
-  --  tag then generate code to check if the external tag of this type is
-  --  the same as the external tag of some other declaration.
+  --  Generate code to check if the external tag of this type is the same
+  --  as the external tag of some other declaration.
 
   -- Check_TSD (TSD'Unrestricted_Access);
 
@@ -6226,16 +6225,16 @@
 
   if not No_Run_Time_Mode
 and then Ada_Version = Ada_2005
-and then Has_External_Tag_Rep_Clause (Typ)
 and then RTE_Available (RE_Check_TSD)
 and then not Debug_Flag_QQ
   then
  Append_To (Elab_Code,
Make_Procedure_Call_Statement (Loc,
- Name = New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
+ Name   =
+   New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
  Parameter_Associations = New_List (
Make_Attribute_Reference (Loc,
- Prefix = New_Occurrence_Of (TSD, Loc),
+ Prefix = New_Occurrence_Of (TSD, Loc),
  Attribute_Name = Name_Unchecked_Access;
   end if;
 
@@ -6810,12 +6809,10 @@
 Expressions = TSD_Aggr_List)));
 
   --  Generate:
-  -- Check_TSD
-  --   (TSD = TSD'Unrestricted_Access);
+  -- Check_TSD (TSD = TSD'Unrestricted_Access);
 
   if Ada_Version = Ada_2005
 and then Is_Library_Level_Entity (Typ)
-and then Has_External_Tag_Rep_Clause (Typ)
 and then RTE_Available (RE_Check_TSD)
 and then not Debug_Flag_QQ
   then


[Ada] Failure to unlock shared passive protected

2014-07-17 Thread Arnaud Charlet
This change addresses a missing unlock operation for the case of a call
to a protected function appearing as the expression of a RETURN statement:
the unlock was inserted after the statement containing the protected function
call, which means that in the case of a RETURN statement it would never be
executed. It is now properly generated as a cleanup action that is executed
in all cases.

The following test case must display '42' without hanging when executed
repeatedly:

$ gnatmake -q shared_prot_func_ret.adb
$ ./shared_prot_func_ret
 42
$ ./shared_prot_func_ret
 42

package body Session_Db is

   type Table_Entry is
  record
 V, N : Integer;
  end record;

   protected Table is
  procedure Add (Name, Value : Integer);

  function Find (Name : Integer) return Integer;
   private
  T : Table_Entry;
   end Table;

   protected body Table is
  procedure Add (Name, Value : Integer)
  is
  begin
 T := (N = Name, V = Value);
  end Add;

  function Find (Name : Integer) return Integer
  is
  begin
 return T.V;
  end Find;
   end Table;

   -
   -- Add --
   -

   procedure Add
 (Name : Integer;
  Value : Integer)
   is
   begin
  Table.Add (Name, Value);
   end Add;

   --
   -- Find --
   --

   function Find (Name : Integer) return Integer is
   begin
  return Table.Find (Name);
   end Find;

end Session_Db;
package Session_Db is
   pragma Shared_Passive;

   procedure Add (Name : Integer;
  Value : Integer);

   function Find (Name : Integer) return Integer;
end Session_Db;
with Session_Db; use Session_Db;
with Ada.Text_IO; use Ada.Text_IO;
procedure Shared_Prot_Func_Ret is
begin
   Session_Db.Add (3, 42);
   Put_Line (Session_Db.Find (3)'Img);
end;

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

2014-07-17  Thomas Quinot  qui...@adacore.com

* sem.ads (Scope_Stack_Entry): Reorganize storage of action lists;
introduce a new list (cleanup actions) for each (transient) scope.
* sinfo.ads, sinfo.adb (Cleanup_Actions): New attribute for
N_Block_Statement
* exp_ch7.ads (Store_Cleanup_Actions_In_Scope): New subprogram.
* exp_ch7.adb (Store_Actions_In_Scope): New subprogram, common
processing for Store_xxx_Actions_In_Scope.
(Build_Cleanup_Statements): Allow for a list of additional
cleanup statements to be passed by the caller.
(Expand_Cleanup_Actions): Take custom cleanup actions associated
with an N_Block_Statement into account.
(Insert_Actions_In_Scope_Around): Account for Scope_Stack_Entry
reorganization (refactoring only, no behaviour change).
(Make_Transient_Block): Add assertion to ensure that the current
scope is indeed a block (namely, the entity for the transient
block being constructed syntactically, which has already been
established as a scope).  If cleanup actions are present in the
transient scope, transfer them now to the transient block.
* exp_ch6.adb (Expand_Protected_Subprogram_Call): Freeze the
called function while it is still present as the name in a call
in the tree. This may not be the case later on if the call is
rewritten into a transient block.
* exp_smem.adb (Add_Shared_Var_Lock_Procs): The post-actions
inserted after calling a protected operation on a shared passive
protected must be performed in a block finalizer, not just
inserted in the tree, so that they are executed even in case of
a normal (RETURN) or abnormal (exception) transfer of control
outside of the current scope.
* exp_smem.ads (Add_Shared_Var_Lock_Procs): Update documentation
* sem_ch8.adb, expander.adb, exp_ch11.adb: Adjust for
Scope_Stack_Entry reorganization.

Index: exp_ch7.adb
===
--- exp_ch7.adb (revision 212718)
+++ exp_ch7.adb (working copy)
@@ -150,6 +150,9 @@
--  ??? The entire comment needs to be rewritten
--  ??? which entire comment?
 
+   procedure Store_Actions_In_Scope (AK : Scope_Action_Kind; L : List_Id);
+   --  Shared processing for Store_xxx_Actions_In_Scope
+
-
-- Finalization Management --
-
@@ -296,11 +299,14 @@
--  Build the deep Initialize/Adjust/Finalize for a record Typ with
--  Has_Controlled_Component set and store them using the TSS mechanism.
 
-   function Build_Cleanup_Statements (N : Node_Id) return List_Id;
+   function Build_Cleanup_Statements
+ (N  : Node_Id;
+  Additional_Cleanup : List_Id) return List_Id;
--  Create the clean up calls for an asynchronous call block, task master,
-   --  protected subprogram body, task allocation block or task body. If the
-   --  context does not contain the above constructs, the routine 

[Ada] Missing finalization of Object.Operation class-wide interface result

2014-07-17 Thread Arnaud Charlet
This patch updates the finalization machinery to recognize a case where the
result of a class-wide interface function call with multiple actual parameters
that appears in Object.Operation format requires finalization actions.


-- Source --


--  types.ads

with Ada.Finalization; use Ada.Finalization;

package Types is
   type Iface is interface;
   type Constructor is tagged null record;

   function Make_Any_Iface
 (C   : in out Constructor;
  Val : Natural) return Iface'Class;

   type Ctrl is new Controlled and Iface with record
  Id : Natural := 0;
   end record;

   procedure Adjust (Obj : in out Ctrl);
   procedure Finalize (Obj : in out Ctrl);
   procedure Initialize (Obj : in out Ctrl);
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
   Id_Gen : Natural := 0;

   procedure Adjust (Obj : in out Ctrl) is
  Old_Id : constant Natural := Obj.Id;
  New_Id : constant Natural := Old_Id * 10;

   begin
  Put_Line (  adj  Old_Id'Img   =  New_Id'Img);
  Obj.Id := New_Id;
   end Adjust;

   procedure Finalize (Obj : in out Ctrl) is
   begin
  Put_Line (  fin  Obj.Id'Img);
   end Finalize;

   procedure Initialize (Obj : in out Ctrl) is
   begin
  Id_Gen := Id_Gen + 1;
  Obj.Id := Id_Gen;
  Put_Line (  ini  Obj.Id'Img);
   end Initialize;

   function Make_Any_Iface
 (C   : in out Constructor;
  Val : Natural) return Iface'Class
   is
  Result : Ctrl;

   begin
  return Result;
   end Make_Any_Iface;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;   use Types;

procedure Main is
begin
   Put_Line (Main start);
   declare
  C : Constructor;
  Obj : Iface'Class := C.Make_Any_Iface (1);
   begin
  null;
   end;
   Put_Line (Main end);
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
Main start
  ini 1
  adj 1 = 10
  fin 1
  adj 10 = 100
  fin 10
  fin 100
Main end

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

2014-07-17  Hristian Kirtchev  kirtc...@adacore.com

* exp_util.adb (Is_Controlled_Function_Call): Recognize a
controlled function call with multiple actual parameters that
appears in Object.Operation form.

Index: exp_util.adb
===
--- exp_util.adb(revision 212655)
+++ exp_util.adb(working copy)
@@ -4214,7 +4214,8 @@
  (Obj_Id : Entity_Id) return Boolean
is
   function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
-  --  Determine if particular node denotes a controlled function call
+  --  Determine if particular node denotes a controlled function call. The
+  --  call may have been heavily expanded.
 
   function Is_Displace_Call (N : Node_Id) return Boolean;
   --  Determine whether a particular node is a call to Ada.Tags.Displace.
@@ -4233,12 +4234,22 @@
   begin
  if Nkind (Expr) = N_Function_Call then
 Expr := Name (Expr);
- end if;
 
- --  The function call may appear in object.operation format
+ --  When a function call appears in Object.Operation format, the
+ --  original representation has two possible forms depending on the
+ --  availability of actual parameters:
+ --
+ --Obj.Func_Call  --  N_Selected_Component
+ --Obj.Func_Call (Param)  --  N_Indexed_Component
 
- if Nkind (Expr) = N_Selected_Component then
-Expr := Selector_Name (Expr);
+ else
+if Nkind (Expr) = N_Indexed_Component then
+   Expr := Prefix (Expr);
+end if;
+
+if Nkind (Expr) = N_Selected_Component then
+   Expr := Selector_Name (Expr);
+end if;
  end if;
 
  return


[Ada] Missing finalization of a transient class-wide function result

2014-07-17 Thread Arnaud Charlet
This patch corrects the transient object machinery to treat the renamed result
of a controlled function call as a finalizable transient when the context is an
expression with actions. If this was a different context, the lifetime of the
result would be considered extended and not finalized.


-- Source --


--  types.ads

with Ada.Finalization; use Ada.Finalization;

package Types is
   type Ctrl is new Limited_Controlled with record
  Val : Integer := 0;
   end record;

   function F1 (Obj : Ctrl) return Integer;
   function F2 (Val : Integer) return Ctrl'Class;
   procedure Finalize (Obj : in out Ctrl);

   procedure Test (Flag : Boolean; Obj : Ctrl);
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
   procedure Finalize (Obj : in out Ctrl) is
   begin
  Put_Line (fin  Obj.Val'Img);
   end Finalize;

   function F1 (Obj : Ctrl) return Integer is
   begin
  return Obj.Val + 1;
   end F1;

   function F2 (Val : Integer) return Ctrl'Class is
   begin
  Put_Line (ini  Val'Img);
  return Ctrl'(Limited_Controlled with Val = Val);
   end F2;

   procedure Test (Flag : Boolean; Obj : Ctrl) is
   begin
  if Flag and then F2 (F1 (Obj)).Val = 42 then
 raise Program_Error;
  end if;
   end Test;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;   use Types;

procedure Main is
begin
   declare
  Obj : Ctrl;
   begin
  Obj.Val := 1;
  Test (True, Obj);
   exception
  when others =
 Put_Line (ERROR: unexpected exception 1);
   end;

   declare
  Obj : Ctrl;
   begin
  Obj.Val := 41;
  Test (True, Obj);
  Put_Line (ERROR: exception not raised);
   exception
  when Program_Error =
 null;
  when others =
 Put_Line (ERROR: unexpected exception 2);
   end;
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
ini 2
fin 2
fin 1
ini 42
fin 42
fin 41

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

2014-07-17  Hristian Kirtchev  kirtc...@adacore.com

* exp_util.adb (Is_Aliased): Transient objects
within an expression with actions cannot be considered aliased.

Index: exp_util.adb
===
--- exp_util.adb(revision 212719)
+++ exp_util.adb(working copy)
@@ -4557,6 +4557,15 @@
   --  Start of processing for Is_Aliased
 
   begin
+ --  Aliasing in expression with actions does not matter because the
+ --  scope of the transient object is always limited by the scope of
+ --  the EWA. Such objects are always hooked and always finalized at
+ --  the end of the EWA's scope.
+
+ if Nkind (Rel_Node) = N_Expression_With_Actions then
+return False;
+ end if;
+
  Stmt := First_Stmt;
  while Present (Stmt) loop
 if Nkind (Stmt) = N_Object_Declaration then
@@ -7343,7 +7352,7 @@
 elsif Is_Access_Type (Obj_Typ)
   and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
   and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
-N_Object_Declaration
+N_Object_Declaration
   and then Is_Finalizable_Transient
  (Status_Flag_Or_Transient_Decl (Obj_Id), Decl)
 then


[Ada] Analysis of delayed SPARK aspects and use of SPARK_Mode

2014-07-17 Thread Arnaud Charlet
This patch ensures that all delayed SPARK aspects are analyzed with the proper
SPARK mode of their related construct.


-- Source --


--  modes.ads

package Modes
  with SPARK_Mode = On,
   Abstract_State = State
is
   Var : Integer := 1;

   procedure Disabled_1 (Formal : Integer)
 with SPARK_Mode = Off,
  Global  = (Input = (Formal, State, Var)),  --  suppressed
  Depends = (null  = (Formal, Var)); --  suppressed

   procedure Enabled_1 (Formal : Integer)
 with SPARK_Mode = On,
  Global  = (Input = (Formal, State, Var)),  --  error
  Depends = (null  = (Formal, Var)); --  error
end Modes;


-- Compilation and output --


$ gcc -c modes.ads
modes.ads:14:33: global item cannot reference parameter of subprogram
modes.ads:14:41: state State must appear in at least one input dependence
  list

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

2014-07-17  Hristian Kirtchev  kirtc...@adacore.com

* sem_ch6.adb (Analyze_Subprogram_Body_Contract,
Analyze_Subprogram_Contract): Add new local variable Mode. Save
and restore the SPARK mode of the related construct in a
stack-like fashion.
* sem_ch7.adb (Analyze_Package_Body_Contract,
Analyze_Package_Contract): Add new local variable Mode. Save and
restore the SPARK mode of the related construct in a stack-like fashion.
* sem_util.adb Remove with and use clause for Opt.
(Restore_SPARK_Mode): New routine.
(Save_SPARK_Mode_And_Set): New routine.
* sem_util.ads Add with and use clause for Opt.
(Restore_SPARK_Mode): New routine.
(Save_SPARK_Mode_And_Set): New routine.

Index: sem_ch7.adb
===
--- sem_ch7.adb (revision 212640)
+++ sem_ch7.adb (working copy)
@@ -180,9 +180,12 @@
 
procedure Analyze_Package_Body_Contract (Body_Id : Entity_Id) is
   Spec_Id : constant Entity_Id := Spec_Entity (Body_Id);
+  Mode: SPARK_Mode_Type;
   Prag: Node_Id;
 
begin
+  Save_SPARK_Mode_And_Set (Body_Id, Mode);
+
   Prag := Get_Pragma (Body_Id, Pragma_Refined_State);
 
   --  The analysis of pragma Refined_State detects whether the spec has
@@ -200,6 +203,8 @@
   then
  Error_Msg_N (package  requires state refinement, Spec_Id);
   end if;
+
+  Restore_SPARK_Mode (Mode);
end Analyze_Package_Body_Contract;
 
-
@@ -839,9 +844,12 @@
--
 
procedure Analyze_Package_Contract (Pack_Id : Entity_Id) is
+  Mode : SPARK_Mode_Type;
   Prag : Node_Id;
 
begin
+  Save_SPARK_Mode_And_Set (Pack_Id, Mode);
+
   --  Analyze the initialization related pragmas. Initializes must come
   --  before Initial_Condition due to item dependencies.
 
@@ -867,6 +875,8 @@
 Check_Missing_Part_Of (Pack_Id);
  end if;
   end if;
+
+  Restore_SPARK_Mode (Mode);
end Analyze_Package_Contract;
 
-
Index: sem_util.adb
===
--- sem_util.adb(revision 212656)
+++ sem_util.adb(working copy)
@@ -41,7 +41,6 @@
 with Nlists;   use Nlists;
 with Nmake;use Nmake;
 with Output;   use Output;
-with Opt;  use Opt;
 with Restrict; use Restrict;
 with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
@@ -15321,6 +15320,15 @@
   Reset_Analyzed (N);
end Reset_Analyzed_Flags;
 
+   
+   -- Restore_SPARK_Mode --
+   
+
+   procedure Restore_SPARK_Mode (Mode : SPARK_Mode_Type) is
+   begin
+  SPARK_Mode := Mode;
+   end Restore_SPARK_Mode;
+

-- Returns_Unconstrained_Type --

@@ -15624,6 +15632,28 @@
   end if;
end Same_Value;
 
+   -
+   -- Save_SPARK_Mode_And_Set --
+   -
+
+   procedure Save_SPARK_Mode_And_Set
+ (Context : Entity_Id;
+  Mode: out SPARK_Mode_Type)
+   is
+  Prag : constant Node_Id := SPARK_Pragma (Context);
+
+   begin
+  --  Save the current mode in effect
+
+  Mode := SPARK_Mode;
+
+  --  Set the mode of the context as the current SPARK mode
+
+  if Present (Prag) then
+ SPARK_Mode := Get_SPARK_Mode_From_Pragma (Prag);
+  end if;
+   end Save_SPARK_Mode_And_Set;
+

-- Scope_Is_Transient --

Index: sem_util.ads
===
--- sem_util.ads(revision 212640)
+++ sem_util.ads(working copy)
@@ -28,6 +28,7 @@
 with Einfo;   use Einfo;
 with Exp_Tss; use Exp_Tss;
 with Namet;   use Namet;
+with Opt; use Opt;
 with Snames;  use Snames;
 with Types; 

[Ada] Eliminate extra unwanted reads of volatile objects

2014-07-17 Thread Arnaud Charlet
This corrects a situation in which extra reads of volatile objects
was being done. It was detected in the case of validity checks
being done on case expressions that were volatile, where two
reads were being done, one for the validity check, and one for
the actual case selection. But the problem is more general and
potentially applies to any situation in which side effects must
be executed only once. Consider this example:

 1. procedure VolCase (X : Natural) is
 2.Y : Natural;
 3.pragma Volatile (Y);
 4.
 5.type R is new Natural;
 6.pragma Volatile (R);
 7.type APtr is access all R;
 8.ARV : APtr := new R'(R(X));
 9.AR : R;
10.
11. begin
12.Y := X;
13.case Y is
14.   when 0 = return;
15.   when 1 .. Natural'Last = null;
16.end case;
17.
18.case ARV.all is
19.   when 0 = return;
20.   when 1 .. R'Last = null;
21.end case;
22.
23.AR := ARV.all ** 4;
24. end;

The first case at line 13 was handled OK, but the second one at line
18 caused two reads, and additionally the exponentiation at line 23
did multiple reads. Now with this fix, we get the following -gnatG
output from this example:

Source recreated from tree for Volcase (body)

with interfaces;

procedure volcase (x : natural) is
   y : natural;
   pragma volatile (y);
   [type volcase__TrB is new integer]
   freeze volcase__TrB []
   type volcase__r is new natural;
   pragma volatile (volcase__r);
   type volcase__aptr is access all volcase__r;
   arv : volcase__aptr := new volcase__r'(volcase__r(x));
   ar : volcase__r;
begin
   y := x;
   R3b : constant natural := y;
   [constraint_error when
 not (interfaces__unsigned_32!(R3b) = 16#7FFF_#)
 invalid data]
   if R3b = 0 then
  return;
   else
  null;
   end if;
   R5b : constant volcase__r := arv.all;
   [constraint_error when
 not (interfaces__unsigned_32!(R5b) = 16#7FFF_#)
 invalid data]
   if R5b = 0 then
  return;
   else
  null;
   end if;
   R7b : constant volcase__r := arv.all;
   R8b : constant volcase__TrB :=
  do
 E6b : constant volcase__TrB := R7b * R7b;
  in E6b * E6b end
   ;
   [constraint_error when
 not (R8b = 0)
 range check failed]
   ar := R8b;
   return;
end volcase;

And as can be seen from the expanded code, there is only one read of the
volatile variable in each of the three cases.

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

2014-07-17  Robert Dewar  de...@adacore.com

* checks.adb (Insert_Valid_Check): Don't insist on a name
for the prefix when we make calls to Force_Evaluation and
Duplicate_Subexpr_No_Checks.
* exp_util.adb (Is_Volatile_Reference): Handle all cases properly
(Remove_Side_Effects): Handle all volatile references right
(Side_Effect_Free): Volatile reference is never side effect free
* sinfo.ads (N_Attribute_Reference): Add comments explaining
that in the tree, the prefix can be a general expression.

Index: exp_util.adb
===
--- exp_util.adb(revision 212721)
+++ exp_util.adb(working copy)
@@ -4238,10 +4238,10 @@
  --  When a function call appears in Object.Operation format, the
  --  original representation has two possible forms depending on the
  --  availability of actual parameters:
- --
- --Obj.Func_Call  --  N_Selected_Component
- --Obj.Func_Call (Param)  --  N_Indexed_Component
 
+ --Obj.Func_Call   N_Selected_Component
+ --Obj.Func_Call (Param)   N_Indexed_Component
+
  else
 if Nkind (Expr) = N_Indexed_Component then
Expr := Prefix (Expr);
@@ -5295,18 +5295,34 @@
 
function Is_Volatile_Reference (N : Node_Id) return Boolean is
begin
-  if Nkind (N) in N_Has_Etype
-and then Present (Etype (N))
-and then Treat_As_Volatile (Etype (N))
-  then
+  --  Only source references are to be treated as volatile, internally
+  --  generated stuff cannot have volatile external effects.
+
+  if not Comes_From_Source (N) then
+ return False;
+
+  --  Never true for reference to a type
+
+  elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
+ return False;
+
+  --  True if object reference with volatile type
+
+  elsif Is_Volatile_Object (N) then
  return True;
 
+  --  True if reference to volatile entity
+
   elsif Is_Entity_Name (N) then
  return Treat_As_Volatile (Entity (N));
 
+  --  True for slice of volatile array
+
   elsif Nkind (N) = N_Slice then
  return Is_Volatile_Reference (Prefix (N));
 
+  --  True if volatile component
+
   elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
  if (Is_Entity_Name 

[Ada] Analysis of delayed SPARK aspects and use of SPARK_Mode

2014-07-17 Thread Arnaud Charlet
This patch clarifies the need of saving and restoring SPARK_Mode in a stack
like fashion. No change in behavior, no test needed.

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

2014-07-17  Hristian Kirtchev  kirtc...@adacore.com

* sem_ch6.adb (Analyze_Subprogram_Body_Contract,
Analyze_Subprogram_Contract): Add comments on SPARK_Mode save/restore.
* sem_ch7.adb (Analyze_Package_Body_Contract,
Analyze_Package_Contract): Add comments on SPARK_Mode save/restore.

Index: sem_ch7.adb
===
--- sem_ch7.adb (revision 212721)
+++ sem_ch7.adb (working copy)
@@ -184,6 +184,11 @@
   Prag: Node_Id;
 
begin
+  --  Due to the timing of contract analysis, delayed pragmas may be
+  --  subject to the wrong SPARK_Mode, usually that of the enclosing
+  --  context. To remedy this, restore the original SPARK_Mode of the
+  --  related package body.
+
   Save_SPARK_Mode_And_Set (Body_Id, Mode);
 
   Prag := Get_Pragma (Body_Id, Pragma_Refined_State);
@@ -204,6 +209,9 @@
  Error_Msg_N (package  requires state refinement, Spec_Id);
   end if;
 
+  --  Restore the SPARK_Mode of the enclosing context after all delayed
+  --  pragmas have been analyzed.
+
   Restore_SPARK_Mode (Mode);
end Analyze_Package_Body_Contract;
 
@@ -848,6 +856,11 @@
   Prag : Node_Id;
 
begin
+  --  Due to the timing of contract analysis, delayed pragmas may be
+  --  subject to the wrong SPARK_Mode, usually that of the enclosing
+  --  context. To remedy this, restore the original SPARK_Mode of the
+  --  related package.
+
   Save_SPARK_Mode_And_Set (Pack_Id, Mode);
 
   --  Analyze the initialization related pragmas. Initializes must come
@@ -876,6 +889,9 @@
  end if;
   end if;
 
+  --  Restore the SPARK_Mode of the enclosing context after all delayed
+  --  pragmas have been analyzed.
+
   Restore_SPARK_Mode (Mode);
end Analyze_Package_Contract;
 
Index: sem_ch6.adb
===
--- sem_ch6.adb (revision 212721)
+++ sem_ch6.adb (working copy)
@@ -2040,6 +2040,11 @@
   Spec_Id : Entity_Id;
 
begin
+  --  Due to the timing of contract analysis, delayed pragmas may be
+  --  subject to the wrong SPARK_Mode, usually that of the enclosing
+  --  context. To remedy this, restore the original SPARK_Mode of the
+  --  related subprogram body.
+
   Save_SPARK_Mode_And_Set (Body_Id, Mode);
 
   --  When a subprogram body declaration is illegal, its defining entity is
@@ -2116,6 +2121,9 @@
  end if;
   end if;
 
+  --  Restore the SPARK_Mode of the enclosing context after all delayed
+  --  pragmas have been analyzed.
+
   Restore_SPARK_Mode (Mode);
end Analyze_Subprogram_Body_Contract;
 
@@ -3693,6 +3701,11 @@
   Seen_In_Post : Boolean := False;
 
begin
+  --  Due to the timing of contract analysis, delayed pragmas may be
+  --  subject to the wrong SPARK_Mode, usually that of the enclosing
+  --  context. To remedy this, restore the original SPARK_Mode of the
+  --  related subprogram body.
+
   Save_SPARK_Mode_And_Set (Subp, Mode);
 
   if Present (Items) then
@@ -3817,6 +3830,9 @@
  end if;
   end if;
 
+  --  Restore the SPARK_Mode of the enclosing context after all delayed
+  --  pragmas have been analyzed.
+
   Restore_SPARK_Mode (Mode);
end Analyze_Subprogram_Contract;
 


[Ada] Implement new partition-wide restriction No_Long_Long_Integer

2014-07-17 Thread Arnaud Charlet
This new restriction No_Long_Long_Integer forbids any explicit reference
to type Standard.Long_Long_Integer, and also forbids declaring range
types whose implicit base type is Long_Long_Integer, and modular types
whose size exceeds Long_Integer'Size. The following is compiled with
-gnatl:

 1. pragma Restrictions (No_Long_Long_Integer);
 2. function NoLLI (m, n : Long_Long_Integer) return Boolean is
   |
 violation of restriction No_Long_Long_Integer at line 1

 3.X : long_Long_Integer := m;
   |
 violation of restriction No_Long_Long_Integer at line 1

 4.type R is range 1 .. Integer'Last + 1;
 |
 violation of restriction No_Long_Long_Integer at line 1

 5.type ROK is range 1 .. Integer'Last;
 6.RV : R := 3;
 7.type LM is mod 2 ** 33;
|
 violation of restriction No_Long_Long_Integer at line 1

 8.type LMOK is mod 2 ** 32;
 9. begin
10.return X  3 and then RV  2;
11. end NoLLI;

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

2014-07-17  Robert Dewar  de...@adacore.com

* restrict.ads (Implementation_Restriction): Add No_Long_Long_Integer.
* s-rident.ads (Partition_Boolean_Restrictions): Add
No_Long_Long_Integer.
* sem_ch3.adb (Modular_Type_Declaration): Size must be =
Long_Integer'Size if restriction No_Long_Long_Integer is active.
(Signed_Integer_Type_Declaration): Do not allow Long_Long_Integer
as the implicit base type for a signed integer type declaration
if restriction No_Long_Long_Integer is active.
* sem_util.ads, sem_util.adb (Set_Entity_With_Checks): Include check for
No_Long_Long_Integer.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 212726)
+++ sem_ch3.adb (working copy)
@@ -17445,6 +17445,10 @@
  M_Val := 2 ** System_Max_Binary_Modulus_Power;
   end if;
 
+  if M_Val  2 ** Standard_Long_Integer_Size then
+ Check_Restriction (No_Long_Long_Integer, Mod_Expr);
+  end if;
+
   Set_Modulus (T, M_Val);
 
   --   Create bounds for the modular type based on the modulus given in
@@ -20622,6 +20626,7 @@
 Base_Typ := Base_Type (Standard_Long_Integer);
 
  elsif Can_Derive_From (Standard_Long_Long_Integer) then
+Check_Restriction (No_Long_Long_Integer, Def);
 Base_Typ := Base_Type (Standard_Long_Long_Integer);
 
  else
Index: sem_util.adb
===
--- sem_util.adb(revision 212723)
+++ sem_util.adb(working copy)
@@ -15980,6 +15980,10 @@
  Check_Restriction (No_Abort_Statements, Post_Node);
   end if;
 
+  if Val = Standard_Long_Long_Integer then
+ Check_Restriction (No_Long_Long_Integer, Post_Node);
+  end if;
+
   --  Check for violation of No_Dynamic_Attachment
 
   if Restriction_Check_Required (No_Dynamic_Attachment)
Index: sem_util.ads
===
--- sem_util.ads(revision 212721)
+++ sem_util.ads(working copy)
@@ -1796,6 +1796,9 @@
--If restriction No_Dynamic_Attachment is set, then it checks that the
--entity is not one of the restricted names for this restriction.
--
+   --If restriction No_Long_Long_Integer is set, then it checks that the
+   --entity is not Standard.Long_Long_Integer.
+   --
--If restriction No_Implementation_Identifiers is set, then it checks
--that the entity is not implementation defined.
 
Index: restrict.ads
===
--- restrict.ads(revision 212640)
+++ restrict.ads(working copy)
@@ -72,7 +72,7 @@
--  restriction to the binder.
 
--  The following declarations establish a mapping between restriction
-   --  identifiers, and the names of corresponding restriction library units.
+   --  identifiers, and the names of corresponding restricted library units.
 
type Unit_Entry is record
   Res_Id : Restriction_Id;
@@ -129,6 +129,7 @@
   No_Implicit_Loops  = True,
   No_Initialize_Scalars  = True,
   No_Local_Protected_Objects = True,
+  No_Long_Long_Integer   = True,
   No_Protected_Type_Allocators   = True,
   No_Relative_Delay  = True,
   No_Requeue_Statements  = True,
Index: s-rident.ads
===
--- s-rident.ads(revision 212640)
+++ s-rident.ads(working copy)
@@ -124,6 +124,7 @@
   No_Local_Allocators,   -- (RM H.4(8))
   No_Local_Timing_Events,-- (RM D.7(10.2/2))
   No_Local_Protected_Objects,

[Ada] Renaming of intrinsic generic subprograms

2014-07-17 Thread Arnaud Charlet
This patch allows the renaming and subsequent instantiation  of generic
subprograms that are marked Intrinsic, such as the predefined units
Unchecked_Conversion and Unchecked_Deallocation.

The following must execute quietly:

   gnatmake -q -gnatws uncrename.adb
   uncrename

---
with Mumble;
with Dumble;
procedure UncRename is

   function Cast is new Mumble (Boolean, Integer);
   X : Boolean := True;
   Y : Integer := Cast (X);

   type A is access all Integer;

   procedure Free is new Dumble (Integer, A);

   Z : A := new Integer;

begin
   Free (Z);
end UncRename;
---
with Ada.Unchecked_Conversion;
generic function Mumble renames Ada.Unchecked_Conversion;
---
with Ada.Unchecked_Deallocation;
generic procedure Dumble renames Ada.Unchecked_Deallocation;

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

2014-07-17  Ed Schonberg  schonb...@adacore.com

* sem_ch8.adb (Analyze_Generic_Renaming): For generic subprograms,
propagate intrinsic flag to renamed entity, to allow e.g. renaming
of Unchecked_Conversion.
* sem_ch3.adb (Analyze_Declarations): Do not analyze contracts
if the declaration has errors.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 212728)
+++ sem_ch3.adb (working copy)
@@ -2366,11 +2366,14 @@
 
   --  Analyze the contracts of subprogram declarations, subprogram bodies
   --  and variables now due to the delayed visibility requirements of their
-  --  aspects.
+  --  aspects. Skip analysis if the declaration already has an error.
 
   Decl := First (L);
   while Present (Decl) loop
- if Nkind (Decl) = N_Object_Declaration then
+ if Error_Posted (Decl) then
+null;
+
+ elsif Nkind (Decl) = N_Object_Declaration then
 Analyze_Object_Contract (Defining_Entity (Decl));
 
  elsif Nkind_In (Decl, N_Abstract_Subprogram_Declaration,
Index: sem_ch8.adb
===
--- sem_ch8.adb (revision 212726)
+++ sem_ch8.adb (working copy)
@@ -706,6 +706,14 @@
 Error_Msg_N (within its scope, generic denotes its instance, N);
  end if;
 
+ --  For subprograms, propagate the Intrinsic flag, to allow, e.g.
+ --  renamings and subsequent instantiations of Unchecked_Conversion.
+
+ if Ekind_In (Old_P, E_Generic_Function, E_Generic_Procedure) then
+Set_Is_Intrinsic_Subprogram
+  (New_P, Is_Intrinsic_Subprogram (Old_P));
+ end if;
+
  Check_Library_Unit_Renaming (N, Old_P);
   end if;
 


[Ada] Add annotate aspect, add entity argument to pragma Annotate

2014-07-17 Thread Arnaud Charlet
An optional final named argument [Entity = local_NAME] is allowed
for pragma Annotate to indicate that the annotation is for a particular
entity, and a corresponding Annotate aspect is introduced.

Given the test program:

 1. package AspectAnn is
 2.Y : constant Integer := 43;
 3.X : Integer;
 4.pragma Annotate (Hello, Goodbye, Y, Entity = X);
 5.Z : Integer with
 6.  Annotate = (Hello, Goodbye, Y),
 7.  Annotate = Hello,
 8.  Annotate = (Goodbye);
 9. end;

Compiling with -gnatG gives:

aspectann_E : short_integer := 0;

package aspectann is
   aspectann__y : constant integer := 43;
   aspectann__x : integer;
   pragma annotate (hello, goodbye, aspectann__y, entity =
 aspectann__x);
   aspectann__z : integer
 with annotate = (hello, goodbye, y),
  annotate = hello,
  annotate = goodbye;
   pragma annotate (hello, goodbye, aspectann__y, entity =
 aspectann__z);
   pragma annotate (hello, entity = aspectann__z);
   pragma annotate (goodbye, entity = aspectann__z);
end aspectann;

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

2014-07-17  Robert Dewar  de...@adacore.com

* aspects.ads, aspects.adb: Add entries for aspect Annotate.
* gnat_rm.texi: Document Entity argument for pragma Annotate and
Annotate aspect.
* sem_ch13.adb (Analyze_Aspect_Specification): Add processing
for Annotate aspect.
* sem_prag.adb (Analyze_Pragma, case Annotate): Allow optional
Entity argument at end.
* sinfo.ads (N_Aspect_Specification): Add note on Annotate aspect.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 212728)
+++ gnat_rm.texi(working copy)
@@ -287,6 +287,7 @@
 Implementation Defined Aspects
 
 * Aspect Abstract_State::
+* Aspect Annotate::
 * Aspect Async_Readers::
 * Aspect Async_Writers::
 * Aspect Contract_Cases::
@@ -1343,7 +1344,7 @@
 @noindent
 Syntax:
 @smallexample @c ada
-pragma Annotate (IDENTIFIER [,IDENTIFIER @{, ARG@}]);
+pragma Annotate (IDENTIFIER [,IDENTIFIER @{, ARG@}] [entity = local_NAME]);
 
 ARG ::= NAME | EXPRESSION
 @end smallexample
@@ -1359,7 +1360,8 @@
 @code{Standard.String} or else @code{Wide_String} or @code{Wide_Wide_String}
 depending on the character literals they contain.
 All other kinds of arguments are analyzed as expressions, and must be
-unambiguous.
+unambiguous. The last argument if present must have the identifier
+@code{Entity} and GNAT verifies that a local name is given.
 
 The analyzed pragma is retained in the tree, but not otherwise processed
 by any part of the GNAT compiler, except to generate corresponding note
@@ -7932,6 +7934,7 @@
 
 @menu
 * Aspect Abstract_State::
+* Aspect Annotate::
 * Aspect Async_Readers::
 * Aspect Async_Writers::
 * Aspect Contract_Cases::
@@ -7981,6 +7984,24 @@
 @noindent
 This aspect is equivalent to pragma @code{Abstract_State}.
 
+@node Aspect Annotate
+@unnumberedsec Annotate
+@findex Annotate
+@noindent
+There are three forms of this aspect (where ID is an identifier,
+and ARG is a general expression).
+
+@table @code
+@item Annotate = ID
+Equivalent to @code{pragma Annotate (ID, Entity = Name);}
+
+@item Annotate = (ID)
+Equivalent to @code{pragma Annotate (ID, Entity = Name);}
+
+@item Annotate = (ID ,ID @{, ARG@})
+Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity = Name);}
+@end table
+
 @node Aspect Async_Readers
 @unnumberedsec Aspect Async_Readers
 @findex Async_Readers
Index: sinfo.ads
===
--- sinfo.ads   (revision 212731)
+++ sinfo.ads   (working copy)
@@ -1966,12 +1966,12 @@
--N_SCIL_Dispatch_Table_Tag_Init node, this is the type being declared).
 
--  SCIL_Controlling_Tag (Node5-Sem)
-   --Present in N_SCIL_Dispatching_Call nodes. References the
-   --controlling tag of a dispatching call. This is usually an
-   --N_Selected_Component node (for a _tag component), but may
-   --be an N_Object_Declaration or N_Parameter_Specification node
-   --in some cases (e.g., for a call to a classwide streaming operation
-   --or to an instance of Ada.Tags.Generic_Dispatching_Constructor).
+   --Present in N_SCIL_Dispatching_Call nodes. References the controlling
+   --tag of a dispatching call. This is usually an N_Selected_Component
+   --node (for a _tag component), but may be an N_Object_Declaration or
+   --N_Parameter_Specification node in some cases (e.g., for a call to
+   --a classwide streaming operation or a call to an instance of
+   --Ada.Tags.Generic_Dispatching_Constructor).
 
--  SCIL_Tag_Value (Node5-Sem)
--Present in N_SCIL_Membership_Test nodes. Used to reference the tag
@@ -7069,6 +7069,10 @@
 
   -- ASPECT_DEFINITION ::= NAME | EXPRESSION
 
+  --  Note that for Annotate, the ASPECT_DEFINITION is a pure positional
+  

[Ada] Crash while processing illegal state refinement

2014-07-17 Thread Arnaud Charlet
This patch modifies the parser to catch a case where the argument of SPARK
aspect Refined_State is not properly parenthesized.


-- Source --


--  no_parens.ads

package No_Parens
  with SPARK_Mode = On,
   Abstract_State = State
is
   pragma Elaborate_Body;
end No_Parens;

--  no_parens.adb

package body No_Parens
  with SPARK_Mode = On,
   Refined_State = State = (Speed, Status)
is
   Speed  : Integer := 0;
   Status : Integer := 0;
end No_Parens;


-- Compilation and output --


$ gcc -c no_parens.adb
no_parens.adb:3:25: missing (

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

2014-07-17  Hristian Kirtchev  kirtc...@adacore.com

* par-ch13.adb (Get_Aspect_Specifications):
Catch a case where the argument of SPARK aspect Refined_State
is not properly parenthesized.

Index: par-ch13.adb
===
--- par-ch13.adb(revision 212640)
+++ par-ch13.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -308,8 +308,8 @@
end if;
 
--  Detect a common error where the non-null definition of
-   --  aspect Depends, Global, Refined_Depends or Refined_Global
-   --  must be enclosed in parentheses.
+   --  aspect Depends, Global, Refined_Depends, Refined_Global
+   --  or Refined_State lacks enclosing parentheses.
 
if Token /= Tok_Left_Paren and then Token /= Tok_Null then
 
@@ -400,6 +400,48 @@
Restore_Scan_State (Scan_State);
 end if;
  end;
+
+  --  Refined_State
+
+  elsif A_Id = Aspect_Refined_State then
+ if Token = Tok_Identifier then
+declare
+   Scan_State : Saved_Scan_State;
+
+begin
+   Save_Scan_State (Scan_State);
+   Scan;  --  past state
+
+   --  The refinement contains a constituent, the whole
+   --  argument of Refined_State must be parenthesized.
+
+   --with Refined_State = State = Constit
+
+   if Token = Tok_Arrow then
+  Restore_Scan_State (Scan_State);
+  Error_Msg_SC -- CODEFIX
+(missing ();
+  Resync_Past_Malformed_Aspect;
+
+  --  Return when the current aspect is the last
+  --  in the list of specifications and the list
+  --  applies to a body.
+
+  if Token = Tok_Is then
+ return Aspects;
+  end if;
+
+   --  The refinement lacks constituents. Do not flag
+   --  this case as the error would be misleading. The
+   --  diagnostic is left to the analysis.
+
+   --with Refined_State = State
+
+   else
+  Restore_Scan_State (Scan_State);
+   end if;
+end;
+ end if;
   end if;
end if;
 


[Ada] Implement No_Standard_Allocators_After_Elaboration

2014-07-18 Thread Arnaud Charlet
This implements the final definition of the Ada 2012 restriction
No_Standard_Allocators_After_Elaboration. There are two static
cases. First appearence in task body, this one we already had
before (compiled with -gnatj55 -gnatld7)

 1. procedure Pmain2 is
 2.type P is access all Integer;
 3.PV : P;
 4.task X;
 5.task body X is
 6.begin
 7.   PV := new Integer;
|
 violation of restriction
No_Standard_Allocators_After_Elaboration
at gnat.adc:1

 8.end;
 9. begin
10.null;
11. end;

Second, also a static case, appearence in a parameterless
library level procedure (same switches)

 1. procedure Pmain is
 2.type R is access all Integer;
 3.RV : R;
 4. begin
 5.RV := new Integer;
 |
 violation of restriction
No_Standard_Allocators_After_Elaboration
at gnat.adc:1

 6. end;

Finally the dynamic case tested at run-time:

 1. with Allocate_After_Elab;
 2. procedure Allocate_After_Elab_Test is
 3. begin
 4.Allocate_After_Elab (42);
 5. end Allocate_After_Elab_Test;

 1. with Ada.Text_IO;
 2. procedure Allocate_After_Elab (X : Integer) is
 3.type Int_Ptr_Type is access Integer;
 4.My_Int_Ptr : Int_Ptr_Type;
 5. begin
 6.My_Int_Ptr := new Integer'(X);
 7.Ada.Text_IO.Put_Line (Have used allocator);
 8. end Allocate_After_Elab;

If we run Allocate_After_Elab_Test, we get:

raised PROGRAM_ERROR : standard allocator after elaboration is complete is not 
allowed
(No_Standard_Allocators_After_Elaboration restriction active)

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

2014-07-18  Robert Dewar  de...@adacore.com

* gcc-interface/Make-lang.in: Add entry for s-elaall.o
* bcheck.adb (Check_Consistent_Restrictions):
Remove obsolete code checking for violation of
No_Standard_Allocators_After_Elaboration (main program)
* bindgen.adb (Gen_Adainit): Handle
No_Standard_Allocators_After_Elaboration
(Gen_Output_File_Ada): ditto.
* exp_ch4.adb (Expand_N_Allocator): Handle
No_Standard_Allocators_After_Elaboration.
* Makefile.rtl: Add entry for s-elaall
* rtsfind.ads: Add entry for Check_Standard_Allocator.
* s-elaall.ads, s-elaall.adb: New files.
* sem_ch4.adb (Analyze_Allocator): Handle
No_Standard_Allocators_After_Elaboration.

Index: bindgen.adb
===
--- bindgen.adb (revision 212735)
+++ bindgen.adb (working copy)
@@ -739,8 +739,8 @@
  if Dispatching_Domains_Used then
 WBI (  procedure Freeze_Dispatching_Domains;);
 WBI (  pragma Import);
-WBI ((Ada, Freeze_Dispatching_Domains,  
- __gnat_freeze_dispatching_domains););
+WBI ((Ada, Freeze_Dispatching_Domains, 
+  __gnat_freeze_dispatching_domains););
  end if;
 
  WBI (   begin);
@@ -749,6 +749,18 @@
  WBI (  end if;);
  WBI (  Is_Elaborated := True;);
 
+ --  Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
+ --  restriction No_Standard_Allocators_After_Elaboration is active.
+
+ if Cumulative_Restrictions.Set
+  (No_Standard_Allocators_After_Elaboration)
+ then
+WBI (  System.Elaboration_Allocators.
+  Mark_Start_Of_Elaboration;);
+ end if;
+
+ --  Generate assignments to initialize globals
+
  Set_String (  Main_Priority := );
  Set_Int(Main_Priority);
  Set_Char   (';');
@@ -996,6 +1008,15 @@
 
   Gen_Elab_Calls;
 
+  --  Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
+  --  restriction No_Standard_Allocators_After_Elaboration is active.
+
+  if Cumulative_Restrictions.Set
+(No_Standard_Allocators_After_Elaboration)
+  then
+ WBI (  System.Elaboration_Allocators.Mark_End_Of_Elaboration;);
+  end if;
+
   --  From this point, no new dispatching domain can be created.
 
   if Dispatching_Domains_Used then
@@ -2482,10 +2503,23 @@
  WBI (with System.Restrictions;);
   end if;
 
+  --  Generate with of Ada.Exceptions if needs library finalization
+
   if Needs_Library_Finalization then
  WBI (with Ada.Exceptions;);
   end if;
 
+  --  Generate with of System.Elaboration_Allocators if the restriction
+  --  No_Standard_Allocators_After_Elaboration was present.
+
+  if Cumulative_Restrictions.Set
+   (No_Standard_Allocators_After_Elaboration)
+  then
+ WBI (with System.Elaboration_Allocators;);
+  end if;
+
+  --  Generate start of package body
+
   WBI ();
   WBI (package body   Ada_Main   is);
  

[Ada] Enforce style check for all binary operators

2014-07-18 Thread Arnaud Charlet
Add two missing style checks for token spacing for binary operators when
switches -gnatyt, -gnatyy or -gnatyg is used.
Preserve previous behavior with debug switch -gnatd.Q

Test:
$ gcc -c pkg.ads -gnatyt -gnatl -gnatd7

Compiling: pkg.ads

 1. package Pkg is
 2.One : constant := 1;
 3.type Entier is range 0 .. 16-One;
   |
 (style) space required

 4.AB : constant String := AB;
  |
 (style) space required

 5. end Pkg;

 5 lines: No errors, 2 warnings

Invoking
   gcc -c pkg.ads -gnatyt -gnatd.Q
should not report any warning.

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

2014-07-18  Vincent Celier  cel...@adacore.com

* par-ch4.adb (Simple_Expression): Add missing style check
for binary adding operators.
(Term): Add missing style check for multiplying operators.

Index: debug.adb
===
--- debug.adb   (revision 212725)
+++ debug.adb   (working copy)
@@ -134,7 +134,7 @@
--  d.N  Add node to all entities
--  d.O  Dump internal SCO tables
--  d.P  Previous (non-optimized) handling of length comparisons
-   --  d.Q
+   --  d.Q  Previous (incomplete) style check for binary operators
--  d.R  Restrictions in ali files in positional form
--  d.S  Force Optimize_Alignment (Space)
--  d.T  Force Optimize_Alignment (Time)
Index: par-ch4.adb
===
--- par-ch4.adb (revision 212656)
+++ par-ch4.adb (working copy)
@@ -2152,6 +2152,11 @@
exit when Token not in Token_Class_Binary_Addop;
Tokptr := Token_Ptr;
Node2 := New_Op_Node (P_Binary_Adding_Operator, Tokptr);
+
+   if Style_Check and then not Debug_Flag_Dot_QQ then
+  Style.Check_Binary_Operator;
+   end if;
+
Scan; -- past operator
Set_Left_Opnd (Node2, Node1);
Node1 := P_Term;
@@ -2406,6 +2411,11 @@
  exit when Token not in Token_Class_Mulop;
  Tokptr := Token_Ptr;
  Node2 := New_Op_Node (P_Multiplying_Operator, Tokptr);
+
+ if Style_Check and then not Debug_Flag_Dot_QQ then
+Style.Check_Binary_Operator;
+ end if;
+
  Scan; -- past operator
  Set_Left_Opnd (Node2, Node1);
  Set_Right_Opnd (Node2, P_Factor);


[Ada] Container Indexing over a derived container type

2014-07-18 Thread Arnaud Charlet
the container type is a derived type, the value of the inherited  aspect is the
Reference (or Constant_Reference) operation declared for the parent type.
However, Reference is also a primitive operation of the new type, and the
inherited operation has a different signature. It is necessary to retrieve the
right operation from the list of primitive operations of the derived type.

Compiling and executing the following must yield:

 2
 10
 111
 1

---
with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
use Ada.Containers;
with Text_IO; use Text_IO;

procedure Derived_Container is

   function Same_Strings (S, T : String) return Boolean is
   begin
  return To_Lower (S) = To_Lower (T);
   end Same_Strings;

   type Place is record
 Page : Positive;
 Line : Positive;
 Col  : Positive;
   end record;

   package Places is new Doubly_Linked_Lists (Place);

   package Indexes is new Indefinite_Hashed_Maps
 (Key_Type= String,
  Element_Type= Places.List,
  Hash= Ada.Strings.Hash,
  Equivalent_Keys = Same_Strings,
  = = Places.=);

   type Text_Map is new Indexes.Map with null record;
   --   with   Variable_Indexing = Reference;
   -- Without aspect, indexing  gives
   --   container cannot be indexed with Cursor

   My_Index : Text_Map;

   My_Place : constant Place := (1, 2, 3);
   
   use type Indexes.Cursor;

   procedure Add_Entry
 (The_Index : in out Text_Map;
  Word  : String;
  P : Place) is

  M_Cursor : Indexes.Cursor;
  New_List : Places.List := Places.Empty_List;

   begin

  M_Cursor := The_Index.Find (Word);
  if M_Cursor /= Indexes.No_Element then
 The_Index (M_Cursor).Append (P);
  else
 New_List.Append (P);
 The_Index.Include (Word, New_List);
  end if;

   end Add_Entry;

begin

   Add_Entry
 (The_Index = My_Index,
  Word  = bill,
  P = My_Place);

   Add_Entry
 (The_Index = My_Index,
  Word  = John,
  P = (10, 10, 10));

   Add_Entry
 (The_Index = My_Index,
  Word  = John,
  P = (111, 333, 999));
   Put_Line (Integer'Image (Integer (My_Index.Length)));
   for Datum of My_Index loop
  for Location of Datum loop
 Put_Line (Integer'Image (Location.Page));
  end loop;
   end loop;
end Derived_Container;

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

2014-07-18  Ed Schonberg  schonb...@adacore.com

* sem_ch4.adb (Try_Container_Indexing):  If the container
type is a derived type, the value of the inherited  aspect is
the Reference operation declared for the parent type. However,
Reference is also a primitive operation of the new type, and
the inherited operation has a different signature. We retrieve
the right one from the list of primitive operations of the
derived type.

Index: sem_ch4.adb
===
--- sem_ch4.adb (revision 212779)
+++ sem_ch4.adb (working copy)
@@ -7020,6 +7020,16 @@
  else
 return False;
  end if;
+
+  --  If the container type is a derived type, the value of the inherited
+  --  aspect is the Reference operation declared for the parent type.
+  --  However, Reference is also a primitive operation of the type, and
+  --  the inherited operation has a different signature. We retrieve the
+  --  right one from the list of primitive operations of the derived type.
+
+  elsif Is_Derived_Type (Etype (Prefix)) then
+ Func := Find_Prim_Op (Etype (Prefix), Chars (Func_Name));
+ Func_Name := New_Occurrence_Of (Func, Loc);
   end if;
 
   Assoc := New_List (Relocate_Node (Prefix));


[Ada] Make sure all rep clauses are removed from tree for -gnatI

2014-07-18 Thread Arnaud Charlet
Previously all rep clauses were ignored in -gnatI mode, but in two
cases (enumeration rep clauses and record rep clauses), they were
not removed from the tree, causing trouble with ASIS tools. These
two cases are now consistent, and ASIS tools will see none of the
ignored rep clauses (e.g. gnatpp will not list ignored rep clauses).

The following test generates no output if compiled with

gcc -c ignorei.ads -gnatI -gnatG log
grep 35 log

 1. package IgnoreI is
 2.type R is record
 3.   X : Integer;
 4.end record;
 5.for R use record
 6.   X at 0 range 0 .. 35;
 7.end record;
 8.type E is (a,b,c);
 9.for E use (0,1,35);
10. end IgnoreI;

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

2014-07-18  Robert Dewar  de...@adacore.com

* freeze.adb (Check_Address_Clause): Use Kill_Rep_Clause (no
functional change).
* gnat_ugn.texi: Document that -gnatI removes rep clauses from
ASIS trees.
* sem_ch13.adb (Kill_Rep_Clause): New procedure
(Analyze_Attribute_Definition_Clause): Use
Kill_Rep_Clause. This is just a cleanup, no functional effect.
(Analyze_Enumeration_Representation_Clause):
Use Kill_Rep_Clause. This means that enum rep
clauses are now properly removed from -gnatct trees.
(Analyze_Record_Representation_Clause): Same change.
* sem_ch13.ads (Kill_Rep_Clause): New procedure.

Index: gnat_ugn.texi
===
--- gnat_ugn.texi   (revision 212782)
+++ gnat_ugn.texi   (working copy)
@@ -4091,6 +4091,12 @@
 Note that this option should be used only for compiling -- the
 code is likely to malfunction at run time.
 
+Note that when @code{-gnatct} is used to generate trees for input
+into @code{ASIS} tools, these representation clauses are removed
+from the tree. This means that the tool will not see them. For
+example, if you use @command{gnatpp} with @code{-gnatI}, the pretty printed
+output will not include the ignored representation clauses.
+
 @item -gnatjnn
 @cindex @option{-gnatjnn} (@command{gcc})
 Reformat error messages to fit on nn character lines
Index: freeze.adb
===
--- freeze.adb  (revision 212737)
+++ freeze.adb  (working copy)
@@ -604,8 +604,10 @@
end if;
 end;
 
-Rewrite (Addr, Make_Null_Statement (Sloc (E)));
+--  And now remove the address clause
 
+Kill_Rep_Clause (Addr);
+
  elsif not Error_Posted (Expr)
and then not Needs_Finalization (Typ)
  then
Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 212782)
+++ sem_ch13.adb(working copy)
@@ -3647,19 +3647,12 @@
  Attribute_Machine_Radix  |
  Attribute_Object_Size|
  Attribute_Size   |
+ Attribute_Small  |
  Attribute_Stream_Size|
  Attribute_Value_Size =
-   Rewrite (N, Make_Null_Statement (Sloc (N)));
+   Kill_Rep_Clause (N);
return;
 
---  Perhaps 'Small should not be ignored by Ignore_Rep_Clauses ???
-
-when Attribute_Small =
-   if Ignore_Rep_Clauses then
-  Rewrite (N, Make_Null_Statement (Sloc (N)));
-  return;
-   end if;
-
 --  The following should not be ignored, because in the first place
 --  they are reasonably portable, and should not cause problems in
 --  compiling code from another target, and also they do affect
@@ -3676,6 +3669,13 @@
  Attribute_Write   =
null;
 
+--  We do not do anything here with address clauses, they will be
+--  removed by Freeze later on, but for now, it works better to
+--  keep then in the tree.
+
+when Attribute_Address =
+   null;
+
 --  Other cases are errors (attribute cannot be set with
 --  definition clause), which will be caught below.
 
@@ -3830,7 +3830,7 @@
 
 --  Even when ignoring rep clauses we need to indicate that the
 --  entity has an address clause and thus it is legal to declare
---  it imported.
+--  it imported. Freeze will get rid of the address clause later.
 
 if Ignore_Rep_Clauses then
if Ekind_In (U_Ent, E_Variable, E_Constant) then
@@ -5365,6 +5365,7 @@
 
begin
   if Ignore_Rep_Clauses then
+ Kill_Rep_Clause (N);
  return;
   end if;
 
@@ -5740,6 +5741,7 @@
 
begin
   if Ignore_Rep_Clauses then
+ Kill_Rep_Clause (N);
  return;
   end if;
 
@@ -10286,6 +10288,16 @@
   end if;

[Ada] Failure to detect illegal parens in static predicate

2014-07-18 Thread Arnaud Charlet
The rules for static predicates do not allow the type name to be
parenthesized. This was not checked, but is now fixed, the following
test now gives the error indicated (compiled with -gnatld7 -gnatj55)
(it used to compile without errors).

 1. package BadParenSP is
 2.subtype r is integer with
 3.  static_predicate = (r)  2;
 |
 expression does not have required form for
static predicate

 4. end;

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

2014-07-18  Robert Dewar  de...@adacore.com

* sem_ch13.adb (Is_Type_Ref): Check that type name is not
parenthesized.

Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 212797)
+++ sem_ch13.adb(working copy)
@@ -6247,7 +6247,8 @@
   pragma Inline (Is_Type_Ref);
   --  Returns if True if N is a reference to the type for the predicate in
   --  the expression (i.e. if it is an identifier whose Chars field matches
-  --  the Nam given in the call).
+  --  the Nam given in the call). N must not be parenthesized, if the type
+  --  name appears in parens, this routine will return False.
 
   function Lo_Val (N : Node_Id) return Uint;
   --  Given static expression or static range from a Static_Predicate list,
@@ -6770,7 +6771,9 @@
 
   function Is_Type_Ref (N : Node_Id) return Boolean is
   begin
- return Nkind (N) = N_Identifier and then Chars (N) = Nam;
+ return Nkind (N) = N_Identifier
+   and then Chars (N) = Nam
+   and then Paren_Count (N) = 0;
   end Is_Type_Ref;
 
   


[Ada] Alternate output modes for GNAT.Memory_Dump

2014-07-18 Thread Arnaud Charlet
Output lines from GNAT.Memory_Dump.Dump can now be prefixed with an offset
relative to the start of the dump, or have no prefix at all, instead of
showing an absolute address.

Test:
$ gnatmake -q dump_test
$ ./dump_test
00: 4C 6F 72 65 6D 20 69 70 73 75 6D 20 64 6F 6C 6F Lorem ipsum dolo
10: 72 20 73 69 74 20 61 6D 65 74 2C 20 63 6F 6E 73 r sit amet, cons
20: 65 63 74 65 74 75 65 72 20 61 64 69 70 69 73 63 ectetuer adipisc
30: 69 6E 67 20 73 65 64 20 64 69 61 6D 20 6E 6F 6E ing sed diam non
40: 75 6D   um

with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Memory_Dump; use GNAT.Memory_Dump;
procedure Dump_Test is
   S : constant String := Lorem ipsum dolor sit amet, consectetuer adipiscing
sed diam nonum;
begin
   Dump (S'Address, S'Length, Offset);
end;

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

2014-07-18  Thomas Quinot  qui...@adacore.com

* g-memdum.adb, g-memdum.ads (Dump): New parameter Prefix, defaulted
to Absolute_Address.

Index: g-memdum.adb
===
--- g-memdum.adb(revision 212640)
+++ g-memdum.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
--- Copyright (C) 2003-2010, AdaCore --
+-- Copyright (C) 2003-2014, AdaCore --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -30,6 +30,7 @@
 --
 
 with System;  use System;
+with System.Img_BIU;  use System.Img_BIU;
 with System.Storage_Elements; use System.Storage_Elements;
 
 with GNAT.IO;  use GNAT.IO;
@@ -43,10 +44,18 @@
-- Dump --
--
 
-   procedure Dump (Addr : System.Address; Count : Natural) is
+   procedure Dump
+ (Addr   : Address;
+  Count  : Natural;
+  Prefix : Prefix_Type := Absolute_Address)
+   is
   Ctr : Natural := Count;
   --  Count of bytes left to output
 
+  Offset_Buf  : String (1 .. Standard'Address_Size / 4 + 4);
+  Offset_Last : Natural;
+  --  Buffer for prefix in Offset mode
+
   Adr : Address := Addr;
   --  Current address
 
@@ -56,14 +65,12 @@
   C : Character;
   --  Character at current storage address
 
-  AIL : constant := Address_Image_Length - 4 + 2;
-  --  Number of chars in initial address + colon + space
+  AIL : Natural;
+  --  Number of chars in prefix (including colon and space)
 
-  Line_Len : constant Natural := AIL + 3 * 16 + 2 + 16;
+  Line_Len : Natural;
   --  Line length for entire line
 
-  Line_Buf : String (1 .. Line_Len);
-
   Hex : constant array (0 .. 15) of Character := 0123456789ABCDEF;
 
   type Char_Ptr is access all Character;
@@ -71,53 +78,89 @@
   function To_Char_Ptr is new Ada.Unchecked_Conversion (Address, Char_Ptr);
 
begin
-  while Ctr /= 0 loop
+  case Prefix is
+ when Absolute_Address =
+AIL := Address_Image_Length - 4 + 2;
+ when Offset =
+Offset_Last := Offset_Buf'First - 1;
+Set_Image_Based_Integer (Ctr, 16, 0, Offset_Buf, Offset_Last);
+AIL := Offset_Last - 4 + 2;
+ when None =
+AIL := 0;
+  end case;
+  Line_Len := AIL + 3 * 16 + 2 + 16;
 
- --  Start of line processing
+  declare
+ Line_Buf : String (1 .. Line_Len);
+  begin
+ while Ctr /= 0 loop
 
- if N = 0 then
-declare
-   S : constant String := Image (Adr);
-begin
-   Line_Buf (1 .. AIL) := S (4 .. S'Length - 1)  : ;
+--  Start of line processing
+
+if N = 0 then
+   case Prefix is
+  when Absolute_Address =
+ declare
+S : constant String := Image (Adr);
+ begin
+Line_Buf (1 .. AIL) := S (4 .. S'Length - 1)  : ;
+ end;
+
+  when Offset =
+ declare
+Last : Natural := 0;
+Len  : Natural;
+ begin
+Set_Image_Based_Integer
+  (Count - Ctr, 16, 0, Offset_Buf, Last);
+Len := Last - 4;
+
+Line_Buf (1 .. AIL - Len - 2) := (others = '0');
+Line_Buf (AIL - Len - 1 .. AIL - 2) :=
+   

[Ada] Allows Wide_String output on Windows console

2014-07-18 Thread Arnaud Charlet
Tested on x86_64-pc-linux-gnu, committed on trunk

2014-07-18  Pascal Obry  o...@adacore.com

* s-crtl.ads, i-cstrea.ads (fputwc): New routine.
* a-witeio.adb (Put): On platforms where there is translation
done by the OS output the raw text.
(New_Line): Use Put above to properly handle the LM wide characters.

Index: sysdep.c
===
--- sysdep.c(revision 212717)
+++ sysdep.c(working copy)
@@ -104,11 +104,12 @@
file positioning function, unless the input operation encounters
end-of-file.
 
-   The other target dependent declarations here are for the two functions
-   __gnat_set_binary_mode and __gnat_set_text_mode:
+   The other target dependent declarations here are for the three functions
+   __gnat_set_binary_mode, __gnat_set_text_mode and __gnat_set_wide_text_mode:
 
   void __gnat_set_binary_mode (int handle);
   void __gnat_set_text_mode   (int handle);
+  void __gnat_set_wide_text_mode   (int handle);
 
These functions have no effect in Unix (or similar systems where there is
no distinction between binary and text files), but in DOS (and similar
@@ -150,6 +151,12 @@
   WIN_SETMODE (handle, O_TEXT);
 }
 
+void
+__gnat_set_wide_text_mode (int handle)
+{
+  WIN_SETMODE (handle, _O_U16TEXT);
+}
+
 #ifdef __CYGWIN__
 
 char *
@@ -245,6 +252,12 @@
 __gnat_set_text_mode (int handle ATTRIBUTE_UNUSED)
 {
 }
+
+void
+__gnat_set_wide_text_mode (int handle ATTRIBUTE_UNUSED)
+{
+}
+
 char *
 __gnat_ttyname (int filedes)
 {
Index: s-crtl.ads
===
--- s-crtl.ads  (revision 212640)
+++ s-crtl.ads  (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- S p e c  --
 --  --
---  Copyright (C) 2003-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 2003-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -122,6 +122,9 @@
function fputc (C : int; stream : FILEs) return int;
pragma Import (C, fputc, fputc);
 
+   function fputwc (C : int; stream : FILEs) return int;
+   pragma Import (C, fputwc, fputwc);
+
function fputs (Strng : chars; Stream : FILEs) return int;
pragma Import (C, fputs, fputs);
 
Index: i-cstrea.ads
===
--- i-cstrea.ads(revision 212640)
+++ i-cstrea.ads(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- S p e c  --
 --  --
---  Copyright (C) 1995-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 1995-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -119,6 +119,9 @@
function fputc (C : int; stream : FILEs) return int
  renames System.CRTL.fputc;
 
+   function fputwc (C : int; stream : FILEs) return int
+ renames System.CRTL.fputwc;
+
function fputs (Strng : chars; Stream : FILEs) return int
  renames System.CRTL.fputs;
 
@@ -223,8 +226,9 @@
--  versa. These functions have no effect if text_translation_required is
--  false (i.e. in normal unix mode). Use fileno to get a stream handle.
 
-   procedure set_binary_mode (handle : int);
-   procedure set_text_mode   (handle : int);
+   procedure set_binary_mode(handle : int);
+   procedure set_text_mode  (handle : int);
+   procedure set_wide_text_mode (handle : int);
 

-- Full Path Name support --
@@ -256,6 +260,7 @@
 
pragma Import (C, set_binary_mode, __gnat_set_binary_mode);
pragma Import (C, set_text_mode, __gnat_set_text_mode);
+   pragma Import (C, set_wide_text_mode, __gnat_set_wide_text_mode);
 
pragma Import (C, max_path_len, __gnat_max_path_len);
pragma Import (C, full_name, __gnat_full_name);
Index: a-witeio.adb
===
--- a-witeio.adb(revision 212640)
+++ a-witeio.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --

[Ada] Primitive operations of incomplete types

2014-07-18 Thread Arnaud Charlet
In Ada 2012, the formals of a subprogram can be incomplete types, and the
subprogram is a primitive operation of the type. If the type is subsequently
derived, it inherits the operation, and it can be explicitly overridden.

   Executing main.adb must yield:

 1
 2

---
with Prim_Test; use Prim_Test;
procedure Main is
   One : T := (Val = 1);
   Two : T := (Val = 2);
begin
   Q (One);
   Q (Two);
end;
--:
package Prim_Test is

   type T;

   procedure P (V  : T);
   procedure Q (It : T);

   type T is record
  Val : Integer;
   end record;

   type T2 is new T;

   overriding procedure P (V : T2);

end Prim_Test;
---
with Text_IO; use Text_IO;
package body Prim_Test is

   procedure P (V : T) is
   begin
  null;
   end P;

   procedure Q (It : T) is
   begin
  Put_Line (Integer'Image (It.Val));
   end;

   overriding procedure P (V : T2) is
   begin
  null;
   end P;

end Prim_Test;

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

2014-07-18  Ed Schonberg  schonb...@adacore.com

* sinfo.ads, sinfo.adb (Incomplete_View): New semantic attribute
of full type declaration, denotes previous declaration for
incomplete view of the type.
* sem_ch3.adb (Analyze_Full_Type_Declaration): Set Incomplete_View
of declaration if one is present.
(Replace_Type): When constructing the signature of an inherited
operation, handle properly the case where the operation has a
formal whose type is an incomplete view.
* sem_util.adb (Collect_Primitive_Operations): Handle properly
the case of an operation declared after an incomplete declaration
for a type T and before the full declaration of T.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 212797)
+++ sem_ch3.adb (working copy)
@@ -2464,6 +2464,8 @@
   Prev := Find_Type_Name (N);
 
   --  The full view, if present, now points to the current type
+  --  If there is an incomplete partial view, set a link to it, to
+  --  simplify the retrieval of primitive operations of the type.
 
   --  Ada 2005 (AI-50217): If the type was previously decorated when
   --  imported through a LIMITED WITH clause, it appears as incomplete
@@ -2472,6 +2474,7 @@
   if Ekind (Prev) = E_Incomplete_Type and then Present (Full_View (Prev))
   then
  T := Full_View (Prev);
+ Set_Incomplete_View (N, Parent (Prev));
   else
  T := Prev;
   end if;
@@ -13537,6 +13540,7 @@
   --
 
   procedure Replace_Type (Id, New_Id : Entity_Id) is
+ Id_Type  : constant Entity_Id := Etype (Id);
  Acc_Type : Entity_Id;
  Par  : constant Node_Id := Parent (Derived_Type);
 
@@ -13547,9 +13551,9 @@
  --  be out of the proper scope for Gigi, so we insert a reference to
  --  it after the derivation.
 
- if Ekind (Etype (Id)) = E_Anonymous_Access_Type then
+ if Ekind (Id_Type) = E_Anonymous_Access_Type then
 declare
-   Desig_Typ : Entity_Id := Designated_Type (Etype (Id));
+   Desig_Typ : Entity_Id := Designated_Type (Id_Type);
 
 begin
if Ekind (Desig_Typ) = E_Record_Type_With_Private
@@ -13567,7 +13571,7 @@
  or else (Is_Interface (Desig_Typ)
and then not Is_Class_Wide_Type (Desig_Typ))
then
-  Acc_Type := New_Copy (Etype (Id));
+  Acc_Type := New_Copy (Id_Type);
   Set_Etype (Acc_Type, Acc_Type);
   Set_Scope (Acc_Type, New_Subp);
 
@@ -13599,16 +13603,23 @@
   Build_Itype_Reference (Acc_Type, Parent (Derived_Type));
 
else
-  Set_Etype (New_Id, Etype (Id));
+  Set_Etype (New_Id, Id_Type);
end if;
 end;
 
- elsif Base_Type (Etype (Id)) = Base_Type (Parent_Type)
+ --  In Ada2012, a formal may have an incomplete type but the type
+ --  derivation that inherits the primitive follows the full view.
+
+ elsif Base_Type (Id_Type) = Base_Type (Parent_Type)
or else
- (Ekind (Etype (Id)) = E_Record_Type_With_Private
-   and then Present (Full_View (Etype (Id)))
+ (Ekind (Id_Type) = E_Record_Type_With_Private
+   and then Present (Full_View (Id_Type))
and then
- Base_Type (Full_View (Etype (Id))) = Base_Type (Parent_Type))
+ Base_Type (Full_View (Id_Type)) = Base_Type (Parent_Type))
+   or else
+ (Ada_Version = Ada_2012
+and then Ekind (Id_Type) = E_Incomplete_Type
+and then Full_View (Id_Type) = Parent_Type)
  then
 --  Constraint checks on formals are generated during expansion,
 --  based on the signature of the original 

[Ada] Reorganize handling of predicates

2014-07-18 Thread Arnaud Charlet
This reorganizes the handling of predicates, in preparation for proper
implementation of real predicates. Several minor errors are corrected
and we properly reject improper static real predicates. Static string
predicates are now always rejected, in line with latest ARG thinking.
The following shows how far we have got. Quite a few minor errors are
fixed in recognizing predicate-static expressions. Still to be done
is actual compile-time testing of real static predicates, and also
noting that constants for which a predicate fails should not be
considered as static.

 1. package TestSP is
 2.subtype F1 is Float with -- OK
 3.  Static_Predicate = F1  0.0 and 4.7  F1;
 4.subtype F2 is Float with -- ERROR
 5.  Static_Predicate = (F2 + 1.0)  0.0 and 4.7  F2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

 6.subtype F3 is Float with -- OK
 7.  Dynamic_Predicate = (F3 + 1.0)  0.0 and 4.7  F3;
 8.subtype F4 is Float with -- OK
 9.  Predicate = (F4 + 1.0)  0.0 and 4.7  F4;
10.
11.subtype S1 is String with -- OK
12.  Static_Predicate = S1  ABC and then DEF = S1;
13.subtype S2 is String with -- ERROR
14.  Static_Predicate = S2'First = 1 and then S2(1) = 'A';
 |
 static predicate not allowed for non-scalar type S2

15.subtype S3 is String with -- OK
16.  Dynamic_Predicate = S3'First = 1 and then S3(1) = 'A';
17.subtype S4 is String with -- OK
18.  Predicate = S4'First = 1 and then S4(1) = 'A';
19.
20.subtype I1 is Integer with -- OK
21.  Static_Predicate = I1  0 and 4  I1;
22.subtype I2 is Integer with -- ERROR
23.  Static_Predicate = (I2 + 1)  0 and 4  I2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

24.subtype I3 is Integer with -- OK
25.  Dynamic_Predicate = (I3 + 1)  0 and 4  I3;
26.subtype I4 is Integer with -- OK
27.  Predicate = (I4 + 1)  0 and 4  I4;
28.subtype I5 is Integer with -- ERROR (not caught before)
29.  Static_Predicate = Boolean'(I5  0);
 |
 expression is not predicate-static (RM 4.3.2(16-22))

30.
31.XF1 : constant F1 := 10.0;
|
 warning: real predicate not applied

32.XF2 : constant F1 := 3.0;
|
 warning: real predicate not applied

33.XF3 : constant := XF1; -- ERROR (not caught yet)
34.
35.XI1 : constant I1 := 10;
|
 warning: static expression fails predicate check on I1

36.XI2 : constant I1 := 3;
37.XI3 : constant := XI1; -- ERROR (not caught yet)
38. end;

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

2014-07-18  Robert Dewar  de...@adacore.com

* einfo.adb (Has_Static_Predicate): New function.
(Set_Has_Static_Predicate): New procedure.
* einfo.ads (Has_Static_Predicate): New flag.
* sem_ch13.adb (Is_Predicate_Static): New function
(Build_Predicate_Functions): Use Is_Predicate_Static to reorganize
(Add_Call): Minor change in Sloc of generated expression
(Add_Predicates): Remove setting of Static_Pred, no longer used.
* sem_ch4.adb (Has_Static_Predicate): Removed this function,
replace by use of the entity flag Has_Static_Predicate_Aspect.
* sem_eval.adb (Eval_Static_Predicate_Check): Check real case
and issue warning that predicate is not checked for now.
* sem_eval.ads (Eval_Static_Predicate_Check): Fix comments in
spec.
* sem_util.adb (Check_Expression_Against_Static_Predicate):
Carry out check for any case where there is a static predicate,
and output appropriate message.
* sinfo.ads: Minor comment corrections.

Index: sinfo.ads
===
--- sinfo.ads   (revision 212802)
+++ sinfo.ads   (working copy)
@@ -4022,13 +4022,13 @@
   --  to deal with, and diagnose a simple expression other than a name for
   --  the right operand. This simplifies error recovery in the parser.
 
-  --  The Alternatives field below is present only if there is more
-  --  than one Membership_Choice present (which is legitimate only in
-  --  Ada 2012 mode) in which case Right_Opnd is Empty, and Alternatives
-  --  contains the list of choices. In the tree passed to the back end,
-  --  Alternatives is always No_List, and Right_Opnd is set (i.e. the
-  --  expansion circuitry expands out the complex set membership case
-  --  using simple membership operations).
+  --  The Alternatives field below is present only if there is more than
+  --  one Membership_Choice present (which is legitimate only in 

[Ada] Constants are non-static if they fail a predicate check

2014-07-18 Thread Arnaud Charlet
If a constant is defined with a static expression, and the expression
statically fails a static predicate, then the constant is not considered
as being static, as shown by this updated example (see last few lines)

 1. package TestSP is
 2.subtype F1 is Float with -- OK
 3.  Static_Predicate = F1  0.0 and 4.7  F1;
 4.subtype F2 is Float with -- ERROR
 5.  Static_Predicate = (F2 + 1.0)  0.0 and 4.7  F2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

 6.subtype F3 is Float with -- OK
 7.  Dynamic_Predicate = (F3 + 1.0)  0.0 and 4.7  F3;
 8.subtype F4 is Float with -- OK
 9.  Predicate = (F4 + 1.0)  0.0 and 4.7  F4;
10.
11.subtype S1 is String with -- OK
12.  Static_Predicate = S1  ABC and then DEF = S1;
13.subtype S2 is String with -- ERROR
14.  Static_Predicate = S2'First = 1 and then S2(1) = 'A';
 |
 static predicate not allowed for non-scalar type S2

15.subtype S3 is String with -- OK
16.  Dynamic_Predicate = S3'First = 1 and then S3(1) = 'A';
17.subtype S4 is String with -- OK
18.  Predicate = S4'First = 1 and then S4(1) = 'A';
19.
20.subtype I1 is Integer with -- OK
21.  Static_Predicate = I1  0 and 4  I1;
22.subtype I2 is Integer with -- ERROR
23.  Static_Predicate = (I2 + 1)  0 and 4  I2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

24.subtype I3 is Integer with -- OK
25.  Dynamic_Predicate = (I3 + 1)  0 and 4  I3;
26.subtype I4 is Integer with -- OK
27.  Predicate = (I4 + 1)  0 and 4  I4;
28.subtype I5 is Integer with -- ERROR (not caught before)
29.  Static_Predicate = Boolean'(I5  0);
 |
 expression is not predicate-static (RM 4.3.2(16-22))

30.
31.XF1 : constant F1 := 10.0; -- WARN (not yet)
|
 warning: real predicate not applied

32.XF2 : constant F1 := 3.0;  -- OK
|
 warning: real predicate not applied

33.XF3 : constant := XF1; -- ERROR (not caught yet)
34.XF4 : constant := XF2; -- OK
35.
36.XI1 : constant I1 := 10; -- WARN
|
 warning: static expression fails predicate check on I1
 warning: expression is no longer considered static

37.XI2 : constant I1 := 3;  -- OK
38.XI3 : constant := XI1;   -- ERROR
 |
 non-static expression used in number declaration
 XI1 is not a static constant (RM 4.9(5))

39.XI4 : constant := XI2;   -- OK
40. end;

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

2014-07-18  Robert Dewar  de...@adacore.com

* sem_util.adb (Check_Expression_Against_Static_Predicate):
Mark expression as non-static if it fails static predicate check,
and issue additional warning.

Index: sem_util.adb
===
--- sem_util.adb(revision 212804)
+++ sem_util.adb(working copy)
@@ -1718,6 +1718,17 @@
  else
 Error_Msg_NE
   (??static expression fails predicate check on , Expr, Typ);
+
+--  We now reset the static expression indication on the expression
+--  since it is no longer static if it fails a predicate test. We
+--  do not do this if the predicate was officially dynamic, since
+--  dynamic predicates don't affect legality in this manner.
+
+if not Has_Dynamic_Predicate_Aspect (Typ) then
+   Error_Msg_N
+ (\??expression is no longer considered static, Expr);
+   Set_Is_Static_Expression (Expr, False);
+end if;
  end if;
   end if;
end Check_Expression_Against_Static_Predicate;


[Ada] Error handling consistency for named associations

2014-07-29 Thread Arnaud Charlet
An error occurring in a subexpression that is part of some construct in
general suppresses the reporting of further errors on the same construct,
to avoid noisy cascaded messages. This patch ensures that this is also
the case when named associations are present.

The following test case must be rejected with the indicated errors only
(note no additional message in the case where a named discriminant
association is used).

$ gcc -c bogus_constraint.ads
bogus_constraint.ads:9:21: Cst1 is not visible
bogus_constraint.ads:9:21: non-visible declaration at line 3
bogus_constraint.ads:10:30: Cst2 is not visible
bogus_constraint.ads:10:30: non-visible declaration at line 4

package Bogus_Constraint is
   package P is
  Cst1 : constant Integer := 1;
  Cst2 : constant Integer := 2;
   end P;

   type R (Start, Endx : Integer) is null record;

   subtype R1 is R (Cst1);
   subtype R2 is R (Start = Cst2);
end Bogus_Constraint;

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

2014-07-29  Thomas Quinot  qui...@adacore.com

* errout.adb (Set_Error_Posted): When propagating flag to
an enclosing named association, also propagate to the parent
of that node, so that named and positional associations are
treated consistently.

Index: errout.adb
===
--- errout.adb  (revision 213154)
+++ errout.adb  (working copy)
@@ -156,11 +156,12 @@
--  variables Msg_Buffer are set on return Msglen.
 
procedure Set_Posted (N : Node_Id);
-   --  Sets the Error_Posted flag on the given node, and all its parents
-   --  that are subexpressions and then on the parent non-subexpression
-   --  construct that contains the original expression (this reduces the
-   --  number of cascaded messages). Note that this call only has an effect
-   --  for a serious error. For a non-serious error, it has no effect.
+   --  Sets the Error_Posted flag on the given node, and all its parents that
+   --  are subexpressions and then on the parent non-subexpression construct
+   --  that contains the original expression. If that parent is a named
+   --  association, the flag is further propagated to its parent. This is done
+   --  in order to guard against cascaded errors. Note that this call has an
+   --  effect for a serious error only.
 
procedure Set_Qualification (N : Nat; E : Entity_Id);
--  Outputs up to N levels of qualification for the given entity. For
@@ -3007,6 +3008,16 @@
 exit when Nkind (P) not in N_Subexpr;
  end loop;
 
+ if Nkind_In (P,
+  N_Pragma_Argument_Association,
+  N_Component_Association,
+  N_Discriminant_Association,
+  N_Generic_Association,
+  N_Parameter_Association)
+ then
+Set_Error_Posted (Parent (P));
+ end if;
+
  --  A special check, if we just posted an error on an attribute
  --  definition clause, then also set the entity involved as posted.
  --  For example, this stops complaining about the alignment after


[Ada] Interface conversions and limited_with clauses.

2014-07-29 Thread Arnaud Charlet
In conversions of prefixed calls involving interfaces, the expression in the
conversion may have a limited view of a type obtained transitively through
several contexts. Use the non-limited view if available, to enable subsequent
interface membership tests.

The following must compile quietly:

   gcc -c rich_graph.adb

---
with Edge;
with Vertex;
with Graph;
package Rich_Graph is
   type Object is new Graph.Object with private;
   type Class_Ref is access all Object'Class;

   overriding function Other_End
 (G : in Object;
  E : in Edge.Class_Ref;
  V : in Vertex.Class_Ref) return Vertex.Class_Ref;

private
   type Object is new Graph.Object with null record;
end Rich_Graph;
---
with Rich_Edge;
with Rich_Vertex;
package body Rich_Graph is
   overriding function Other_End
 (G : in Object;
  E : in Edge.Class_Ref;
  V : in Vertex.Class_Ref) return Vertex.Class_Ref
   is
  Rich_E : Rich_Edge.Class_Ref;
  Rich_V : Rich_Vertex.Class_Ref;

   begin
  Rich_E := Rich_Edge.Class_Ref (E);
  Rich_V := Rich_Vertex.Class_Ref (V);

  return Vertex.Class_Ref (Rich_E.Other_End (Rich_V));
   end Other_End;
end Rich_Graph;
---
package Edge is
   type Object is limited interface;
   type Class_Ref is access all Object'Class;
end Edge;
---
package Vertex is
   type Object is limited interface;
   type Class_Ref is access all Object'Class;
end Vertex;
---
with Vertex;
with Edge;
package Graph is
   type Object is limited interface;
   type Class_Ref is access all Object'Class;

   function Other_End
 (Graph : in Object;
  E : in Edge.Class_Ref;
  V : in Vertex.Class_Ref) return Vertex.Class_Ref is abstract;
end Graph;
---
with Edge;
limited with Rich_Vertex;
package Rich_Edge is
   type Object is limited interface and Edge.Object;
   type Class_Ref is access all Object'Class;

   function Other_End
 (E : in Object;
  V : access Rich_Vertex.Object'Class)
  return Rich_Vertex.Class_Ref is abstract;
end Rich_Edge;
---
with Vertex;
package Rich_Vertex is
   type Object is limited interface and Vertex.Object;
   type Class_Ref is access all Object'Class;
end Rich_Vertex;

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

2014-07-29  Ed Schonberg  schonb...@adacore.com

* sem_res.adb (Resolve_Type_Conversion): If the type of the
expression is a limited view, use the non-limited view when
available.

Index: sem_res.adb
===
--- sem_res.adb (revision 213154)
+++ sem_res.adb (working copy)
@@ -10193,6 +10193,17 @@
 Target : Entity_Id := Target_Typ;
 
  begin
+--  If the type of the operand is a limited view, use the non-
+--  limited view when available.
+
+if From_Limited_With (Opnd)
+  and then Ekind (Opnd) in Incomplete_Kind
+  and then Present (Non_Limited_View (Opnd))
+then
+   Opnd := Non_Limited_View (Opnd);
+   Set_Etype (Expression (N), Opnd);
+end if;
+
 if Is_Access_Type (Opnd) then
Opnd := Designated_Type (Opnd);
 end if;


[Ada] Undefined symbols when building GPS

2014-07-29 Thread Arnaud Charlet
This patch ensures that abort-related expansion generates the same amount of
internal entities when aborts are allowed or are being suppressed by pragma
Restriction (No_Abort_Statements).

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

2014-07-29  Hristian Kirtchev  kirtc...@adacore.com

* exp_ch3.adb (Default_Initialize_Object): Add new variables
Abrt_Blk and Dummy. Generate a dummy temporary when aborts are
not allowed to ensure the symmetrical generation of symbols.
* exp_ch7.adb (Build_Object_Declarations): Remove variables A_Expr
and E_Decl. Add new variables Decl and Dummy. Generate a dummy
temporary when aborts are not allowed to ensure symmertrical
generation of symbols.
* exp_intr.adb (Expand_Unc_Deallocation): Add new variable
Dummy. Generate a dummy temporary when aborts are not allowed
to ensure symmertrical generation of symbols.

Index: exp_ch7.adb
===
--- exp_ch7.adb (revision 213156)
+++ exp_ch7.adb (working copy)
@@ -3134,9 +3134,13 @@
   Loc : Source_Ptr;
   For_Package : Boolean := False)
is
-  A_Expr : Node_Id;
-  E_Decl : Node_Id;
+  Decl : Node_Id;
 
+  Dummy : Entity_Id;
+  pragma Unreferenced (Dummy);
+  --  This variable captures an unused dummy internal entity, see the
+  --  comment associated with its use.
+
begin
   pragma Assert (Decls /= No_List);
 
@@ -3164,56 +3168,61 @@
   --  does not include routine Raise_From_Controlled_Operation which is the
   --  the sole user of flag Abort.
 
-  --  This is not needed for library-level finalizers as they are called
-  --  by the environment task and cannot be aborted.
+  --  This is not needed for library-level finalizers as they are called by
+  --  the environment task and cannot be aborted.
 
-  if Abort_Allowed
-and then VM_Target = No_VM
-and then not For_Package
-  then
- Data.Abort_Id  := Make_Temporary (Loc, 'A');
+  if VM_Target = No_VM and then not For_Package then
+ if Abort_Allowed then
+Data.Abort_Id := Make_Temporary (Loc, 'A');
 
- A_Expr := New_Occurrence_Of (RTE (RE_Triggered_By_Abort), Loc);
+--  Generate:
+--Abort_Id : constant Boolean := A_Expr;
 
- --  Generate:
+Append_To (Decls,
+  Make_Object_Declaration (Loc,
+Defining_Identifier = Data.Abort_Id,
+Constant_Present= True,
+Object_Definition   =
+  New_Occurrence_Of (Standard_Boolean, Loc),
+Expression  =
+  New_Occurrence_Of (RTE (RE_Triggered_By_Abort), Loc)));
 
- --Abort_Id : constant Boolean := A_Expr;
+ --  Abort is not required
 
- Append_To (Decls,
-   Make_Object_Declaration (Loc,
- Defining_Identifier = Data.Abort_Id,
- Constant_Present= True,
- Object_Definition   = New_Occurrence_Of (Standard_Boolean, Loc),
- Expression  = A_Expr));
+ else
+--  Generate a dummy entity to ensure that the internal symbols are
+--  in sync when a unit is compiled with and without aborts.
 
+Dummy := Make_Temporary (Loc, 'A');
+Data.Abort_Id := Empty;
+ end if;
+
+  --  .NET/JVM or library-level finalizers
+
   else
- --  No abort, .NET/JVM or library-level finalizers
-
- Data.Abort_Id  := Empty;
+ Data.Abort_Id := Empty;
   end if;
 
   if Exception_Extra_Info then
- Data.E_Id  := Make_Temporary (Loc, 'E');
+ Data.E_Id := Make_Temporary (Loc, 'E');
 
  --  Generate:
-
  --E_Id : Exception_Occurrence;
 
- E_Decl :=
+ Decl :=
Make_Object_Declaration (Loc,
  Defining_Identifier = Data.E_Id,
  Object_Definition   =
New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc));
- Set_No_Initialization (E_Decl);
+ Set_No_Initialization (Decl);
 
- Append_To (Decls, E_Decl);
+ Append_To (Decls, Decl);
 
   else
- Data.E_Id  := Empty;
+ Data.E_Id := Empty;
   end if;
 
   --  Generate:
-
   --Raised_Id : Boolean := False;
 
   Append_To (Decls,
Index: exp_intr.adb
===
--- exp_intr.adb(revision 213156)
+++ exp_intr.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+--  

[Ada] Missing finalization of a transient class-wide function result

2014-07-29 Thread Arnaud Charlet
This patch corrects the transient object machinery to disregard aliasing when
the associated context is a Boolean expression with actions. This is because
the Boolean result is always known after the action list has been evaluated,
therefore the transient objects must be finalized at that point.


-- Source --


--  types.ads

with Ada.Finalization; use Ada.Finalization;

package Types is
   type Ctrl is new Limited_Controlled with record
  Val : Integer := 0;
   end record;

   function F1 (Obj : Ctrl) return Integer;
   function F2 (Val : Integer) return Ctrl'Class;
   procedure Finalize (Obj : in out Ctrl);

   procedure Test (Flag : Boolean; Obj : Ctrl);
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
   procedure Finalize (Obj : in out Ctrl) is
   begin
  Put_Line (fin  Obj.Val'Img);
   end Finalize;

   function F1 (Obj : Ctrl) return Integer is
   begin
  return Obj.Val + 1;
   end F1;

   function F2 (Val : Integer) return Ctrl'Class is
   begin
  Put_Line (ini  Val'Img);
  return Ctrl'(Limited_Controlled with Val = Val);
   end F2;

   procedure Test (Flag : Boolean; Obj : Ctrl) is
   begin
  if Flag and then F2 (F1 (Obj)).Val = 42 then
 raise Program_Error;
  end if;
   end Test;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;   use Types;

procedure Main is
begin
   declare
  Obj : Ctrl;
   begin
  Obj.Val := 1;
  Test (True, Obj);
   exception
  when others =
 Put_Line (ERROR: unexpected exception 1);
   end;

   declare
  Obj : Ctrl;
   begin
  Obj.Val := 41;
  Test (True, Obj);
  Put_Line (ERROR: exception not raised);
   exception
  when Program_Error =
 null;
  when others =
 Put_Line (ERROR: unexpected exception 2);
   end;
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
ini 2
fin 2
fin 1
ini 42
fin 42
fin 41

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

2014-07-29  Hristian Kirtchev  kirtc...@adacore.com

* exp_ch4.adb (Process_Transient_Object): Remove constant
In_Cond_Expr, use its initialization expression in place.
* exp_ch7.adb (Process_Declarations): There is no need to check
that a transient object being hooked is controlled as it would
not have been hooked in the first place.
* exp_util.adb (Is_Aliased): 'Reference-d or renamed transient
objects are not considered aliased when the related context is
a Boolean expression_with_actions.
(Requires_Cleanup_Actions): There is no need to check that a transient
object being hooked is controlled as it would not have been hooked in
the first place.

Index: exp_ch4.adb
===
--- exp_ch4.adb (revision 213156)
+++ exp_ch4.adb (working copy)
@@ -12616,9 +12616,6 @@
   --  If False, call to finalizer includes a test of whether the hook
   --  pointer is null.
 
-  In_Cond_Expr : constant Boolean :=
-   Within_Case_Or_If_Expression (Rel_Node);
-
begin
   --  Step 0: determine where to attach finalization actions in the tree
 
@@ -12636,10 +12633,10 @@
  --  conditional expression.
 
  Finalize_Always :=
-not (In_Cond_Expr
-  or else
-Nkind_In (Original_Node (Rel_Node), N_Case_Expression,
-N_If_Expression));
+   not Within_Case_Or_If_Expression (Rel_Node)
+ and then not Nkind_In
+(Original_Node (Rel_Node), N_Case_Expression,
+   N_If_Expression);
 
  declare
 Loc  : constant Source_Ptr := Sloc (Rel_Node);
Index: exp_ch7.adb
===
--- exp_ch7.adb (revision 213157)
+++ exp_ch7.adb (working copy)
@@ -1817,9 +1817,7 @@
elsif Is_Access_Type (Obj_Typ)
  and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
  and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
-N_Object_Declaration
- and then Is_Finalizable_Transient
-(Status_Flag_Or_Transient_Decl (Obj_Id), Decl)
+   N_Object_Declaration
then
   Processing_Actions (Has_No_Init = True);
 
Index: exp_util.adb
===
--- exp_util.adb(revision 213156)
+++ exp_util.adb(working copy)
@@ -3435,9 +3435,8 @@
or else Etype (Assoc_Node) /= Standard_Void_Type)
 and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
 and then 

[Ada] New pragma Unevaluated_Use_Of_Old

2014-07-29 Thread Arnaud Charlet
A new pragma Unevaluated_Use_Of_Old (Error | Warn | Allow) is
implemented which controls the processing of attributes Old and
Loop_Entry. If either of these attributes is used in a potentially
unevaluated expression  e.g. the then or else parts of an if
expression), then normally this usage is considered illegal if
the prefix of the attribute is other than an entity name. The
language requires this behavior for Old, and GNAT copies the
same rule for Loop_Entry.

Although the rule avoids this possibility, it is sometimes
too restrictive. The pragma Unevaluated_Use_Of_Old can be
used to modify this behavior. If the argument is ERROR, then an
error is given (this is the default RM behavior). If the argument is
WARN then the usage is allowed as legal but with a warning
that an exception might be raised. If the argument is ALLOW
then the usage is allowed as legal without generating a warning.

This pragma may appear as a configuration pragma, or in a declarative
part or package specification. In the latter case it applies to
uses up to the end of the corresponding statement sequence or
sequence of package declarations.

The following is compiled with -gnatc -gnatwW -gnatld7 -gnatj60

 1. package UnevalOld is
 2.K : Character;
 3.procedure U (A : String; C : Boolean)  -- ERROR
 4.  with Post = (if C then A(1)'Old = K else True);
 |
 prefix of attribute Old that is potentially
unevaluated must denote an entity

 5.procedure V (A : String; C : Boolean)
 6.  with Post = A(1)'Old = K;
 7.
 8.package U1 is
 9.   pragma Unevaluated_Use_Of_Old (Warn); -- WARNING
10.   procedure P1 (A : String; C : Boolean)
11. with Post = (if C then A(1)'Old = K else True);
|
 warning: prefix of attribute Old appears in
potentially unevaluated context, exception may
be raised

12.end U1;
13.
14.package U2 is
15.   pragma Unevaluated_Use_Of_Old (Allow); -- OK
16.   procedure P2 (A : String; C : Boolean)
17. with Post = (if C then A(1)'Old = K else True);
18.end U2;
19. end;

If the same compilation is carried out with a gnat.adc file that
contains the pragma:

pragma Unevaluated_Use_Of_Old (Allow);

Then the output omits the first error:

 1. package UnevalOld is
 2.K : Character;
 3.procedure U (A : String; C : Boolean)  -- ERROR
 4.  with Post = (if C then A(1)'Old = K else True);
 5.procedure V (A : String; C : Boolean)
 6.  with Post = A(1)'Old = K;
 7.
 8.package U1 is
 9.   pragma Unevaluated_Use_Of_Old (Warn); -- WARNING
10.   procedure P1 (A : String; C : Boolean)
11. with Post = (if C then A(1)'Old = K else True);
|
 warning: prefix of attribute Old appears in
potentially unevaluated context, exception may
be raised

12.end U1;
13.
14.package U2 is
15.   pragma Unevaluated_Use_Of_Old (Allow); -- OK
16.   procedure P2 (A : String; C : Boolean)
17. with Post = (if C then A(1)'Old = K else True);
18.end U2;
19. end;

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

2014-07-29  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document pragma Unevaluated_Use_Of_Old.
* opt.adb: Handle Uneval_Old.
* opt.ads (Uneval_Old, Uneval_Old_Config): New variables.
* par-prag.adb: Add dummy entry for pragma Unevaluated_Use_Of_Old.
* sem.ads (Save_Uneval_Old): New field in Scope_Stack_Entry.
* sem_attr.adb (Uneval_Old_Msg): New procedure.
* sem_ch8.adb (Push_Scope): Save Uneval_Old.
(Pop_Scope): Restore Uneval_Old.
* sem_prag.adb (Analyze_Pragma, case Unevaluated_Use_Of_Old):
Implemented.
* snames.ads-tmpl: Add entries for pragma Unevaluated_Use_Of_Old
Add entries for Name_Warn, Name_Allow.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 213156)
+++ gnat_rm.texi(working copy)
@@ -270,6 +270,7 @@
 * Pragma Type_Invariant::
 * Pragma Type_Invariant_Class::
 * Pragma Unchecked_Union::
+* Pragma Unevaluated_Use_Of_Old::
 * Pragma Unimplemented_Unit::
 * Pragma Universal_Aliasing ::
 * Pragma Universal_Data::
@@ -1119,6 +1120,7 @@
 * Pragma Type_Invariant::
 * Pragma Type_Invariant_Class::
 * Pragma Unchecked_Union::
+* Pragma Unevaluated_Use_Of_Old::
 * Pragma Unimplemented_Unit::
 * Pragma Universal_Aliasing ::
 * Pragma Universal_Data::
@@ -7242,6 +7244,59 @@
 version in all language modes (Ada 83, Ada 95, and Ada 2005). For full
 details, consult the Ada 2012 Reference Manual, section B.3.3.
 
+@node Pragma Unevaluated_Use_Of_Old
+@unnumberedsec Pragma Unevaluated_Use_Of_Old
+@cindex 

[Ada] Cleanup handling of discrete static predicates

2014-07-29 Thread Arnaud Charlet
This is just an internal cleanup, involving some name changes
and slightly cleaned up testing of flags etc. This is part of
the preparation for implementing static real predicates. No
functional effect.

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

2014-07-29  Robert Dewar  de...@adacore.com

* sem_aggr.adb, exp_ch5.adb, sem_ch5.adb, exp_util.adb, einfo.adb,
einfo.ads, sem_util.adb, sem_attr.adb, sem_case.adb, sem_eval.adb,
sem_eval.ads, sem_ch13.adb: General cleanup of static predicate
handling. Change name of Discrete_Predicate to
Discrete_Static_Predicate, and replace testing of the presence of this
field by testing the flag Has_Static_Expression.

Index: sem_aggr.adb
===
--- sem_aggr.adb(revision 213159)
+++ sem_aggr.adb(working copy)
@@ -1721,11 +1721,11 @@
 --  original choice with the list of individual values
 --  covered by the predicate.
 
-if Present (Static_Predicate (E)) then
+if Present (Static_Discrete_Predicate (E)) then
Delete_Choice := True;
 
New_Cs := New_List;
-   P := First (Static_Predicate (E));
+   P := First (Static_Discrete_Predicate (E));
while Present (P) loop
   C := New_Copy (P);
   Set_Sloc (C, Sloc (Choice));
Index: exp_ch5.adb
===
--- exp_ch5.adb (revision 213159)
+++ exp_ch5.adb (working copy)
@@ -3977,7 +3977,7 @@
   LPS : constant Node_Id:= Loop_Parameter_Specification (Isc);
   Loop_Id : constant Entity_Id  := Defining_Identifier (LPS);
   Ltype   : constant Entity_Id  := Etype (Loop_Id);
-  Stat: constant List_Id:= Static_Predicate (Ltype);
+  Stat: constant List_Id:= Static_Discrete_Predicate (Ltype);
   Stmts   : constant List_Id:= Statements (N);
 
begin
Index: sem_ch5.adb
===
--- sem_ch5.adb (revision 213159)
+++ sem_ch5.adb (working copy)
@@ -2480,8 +2480,8 @@
  --  function only, look for a dynamic predicate aspect as well.
 
  if Is_Discrete_Type (Entity (DS))
-   and then Present (Predicate_Function (Entity (DS)))
-   and then (No (Static_Predicate (Entity (DS)))
+   and then Has_Predicates (Entity (DS))
+   and then (not Has_Static_Predicate (Entity (DS))
   or else Has_Dynamic_Predicate_Aspect (Entity (DS)))
  then
 Bad_Predicated_Subtype_Use
Index: exp_util.adb
===
--- exp_util.adb(revision 213158)
+++ exp_util.adb(working copy)
@@ -1980,7 +1980,7 @@
 --  if the list is empty, corresponding to a False predicate, then
 --  no choices are inserted.
 
-P := First (Static_Predicate (Entity (Choice)));
+P := First (Static_Discrete_Predicate (Entity (Choice)));
 while Present (P) loop
 
--  If low bound and high bounds are equal, copy simple choice
Index: einfo.adb
===
--- einfo.adb   (revision 213160)
+++ einfo.adb   (working copy)
@@ -222,7 +222,7 @@
--DT_Offset_To_Top_Func   Node25
--PPC_Wrapper Node25
--Related_Array_ObjectNode25
-   --Static_PredicateList25
+   --Static_Discrete_Predicate   List25
--Task_Body_Procedure Node25
 
--Dispatch_Table_Wrappers Elist26
@@ -2971,11 +2971,11 @@
   return Node19 (Id);
end Spec_Entity;
 
-   function Static_Predicate (Id : E) return S is
+   function Static_Discrete_Predicate (Id : E) return S is
begin
   pragma Assert (Is_Discrete_Type (Id));
   return List25 (Id);
-   end Static_Predicate;
+   end Static_Discrete_Predicate;
 
function Status_Flag_Or_Transient_Decl (Id : E) return N is
begin
@@ -5761,11 +5761,11 @@
   Set_Node19 (Id, V);
end Set_Spec_Entity;
 
-   procedure Set_Static_Predicate (Id : E; V : S) is
+   procedure Set_Static_Discrete_Predicate (Id : E; V : S) is
begin
   pragma Assert (Is_Discrete_Type (Id) and then Has_Predicates (Id));
   Set_List25 (Id, V);
-   end Set_Static_Predicate;
+   end Set_Static_Discrete_Predicate;
 
procedure Set_Status_Flag_Or_Transient_Decl (Id : E; V : E) is
begin
@@ -9404,7 +9404,7 @@
   E_Modular_Integer_Type   |
   E_Modular_Integer_Subtype|
   E_Signed_Integer_Subtype =
-Write_Str 

[Ada] Implement static predicates for string/real types

2014-07-29 Thread Arnaud Charlet
This implements static predicates for string and real types,
as defined in the RM. There is one exception, which is that
the RM allows X  ABC as being predicate static, but since
ABC  ABA is not static, that's peculiar, so we assume
that this is a mistake in the RM, and that string comparisons
should not be permitted as predicate-static.

The following test program shows various uses of static
predicates of all types with a range of legality tests
and tests for compile time evaluation of static predicates.

 1. package TestSP is
 2.subtype F1 is Float with -- OK
 3.Static_Predicate = F1  0.0 and 4.7  F1;
 4.
 5.subtype F1a is F1 with -- OK
 6.  Static_Predicate = F1a  2.4;
 7.
 8.subtype F2 is Float with -- ERROR
 9.  Static_Predicate = (F2 + 1.0)  0.0 and 4.7  F2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

10.subtype F3 is Float with -- OK
11.  Dynamic_Predicate = (F3 + 1.0)  0.0 and 4.7  F3;
12.subtype F4 is Float with -- OK
13.  Predicate = (F4 + 1.0)  0.0 and 4.7  F4;
14.
15.subtype S0 is String with -- ERROR
16.  Static_Predicate = S0  ABC and then DEF = S0;
 |
 expression is not predicate-static (RM 4.3.2(16-22))

17.subtype S1 is String with -- OK
18.  Static_Predicate = S1 in ABC | DEF;
19.
20.subtype S2 is String with -- ERROR
21.  Static_Predicate = S2'First = 1 and then S2(1) = 'A';
 |
 expression is not predicate-static (RM 4.3.2(16-22))

22.subtype S3 is String with -- OK
23.  Dynamic_Predicate = S3'First = 1 and then S3(1) = 'A';
24.subtype S4 is String with -- OK
25.  Predicate = S4'First = 1 and then S4(1) = 'A';
26.subtype S5 is String with -- OK
27.  Predicate = S5 in ABC | DEF;
28.subtype S6 is String with -- OK
29.  Dynamic_Predicate = S6 in ABC | DEF;
30.
31.subtype I1 is Integer with -- OK
32.  Static_Predicate = I1  0 and 4  I1;
33.subtype I1a is I1 with -- OK
34.  Static_Predicate = I1a  2;
35.
36.subtype I2 is Integer with -- ERROR
37.  Static_Predicate = (I2 + 1)  0 and 4  I2;
  |
 expression is not predicate-static (RM 4.3.2(16-22))

38.subtype I3 is Integer with -- OK
39.  Dynamic_Predicate = (I3 + 1)  0 and 4  I3;
40.subtype I4 is Integer with -- OK
41.  Predicate = (I4 + 1)  0 and 4  I4;
42.
43.subtype I5 is Integer with -- ERROR
44.  Static_Predicate = Boolean'(I5  0);
 |
 expression is not predicate-static (RM 4.3.2(16-22))

45.
46.XF1 : constant F1 := 10.0; -- WARN
|
 warning: static expression fails static predicate
check on F1, expression is no longer considered
static

47.XF2 : constant F1 := 3.0;  -- OK
48.
49.XF3 : constant := XF1; -- ERROR
 |
 non-static expression used in number declaration
 XF1 is not a static constant (RM 4.9(5))

50.XF4 : constant := XF2; -- OK
51.
52.XF1a : constant F1a := 1.3; -- WARN;
  |
 warning: static expression fails static predicate
check on F1a, expression is no longer considered
static

53.XF1b : constant F1a := 5.3; -- WARN;
  |
 warning: static expression fails static predicate
check on F1a, expression is no longer considered
static

54.XF1c : constant F1a := 3.7; -- OK
55.
56.XI1 : constant I1 := 10; -- WARN
|
 warning: static expression fails static predicate
check on I1, expression is no longer considered
static

57.XI2 : constant I1 := 3;  -- OK
58.
59.XI3 : constant := XI1;   -- ERROR
 |
 non-static expression used in number declaration
 XI1 is not a static constant (RM 4.9(5))

60.XI4 : constant := XI2;   -- OK
61.
62.XI1a : constant I1a := 2; -- WARN
  |
 warning: static expression fails static predicate
check on I1a, expression is no longer considered
static

63.XI1b : constant I1a := 7; -- WARN
  |
 warning: static expression fails static predicate
check on I1a, expression is no longer considered
static

64.XI1c : constant I1a := 3; -- OK
65.
66.XSa : constant S1 := ABC; -- OK
67.
68.Xsb : constant S1 := DQR; -- WARN
|
 warning: 

[Ada] New pragma Default_Scalar_Storage_Order

2014-07-29 Thread Arnaud Charlet
Normally the default scalar storage order is the native order of the
target. This pragma, which can be either a configuration pragma, or
appear in a package spec or declarative part, can provide a default
value that overrides this normal default. If used in a package spec
or declarative part, it applies to the following declarations of
array and record types in that package spec or declarative part.
The following example shows the pragma in action:

 1. pragma Default_Scalar_Storage_Order
 2.  (High_Order_First);
 3. with System; use System;
 4. package DSSO1 is
 5.type H1 is record
 6.   --  High from config pragma
 7.   a : Integer;
 8.end record;
 9.for H1 use record
10.  a at 0 range 0 .. 31;
11.end record;
12.
13.type L2 is record
14.   --  Low from explicit setting
15.   a : Integer;
16.end record;
17.for L2 use record
18.   a at 0 range 0 .. 31;
19.end record;
20.for L2'Scalar_Storage_Order
21.use Low_Order_First;
22.
23.type L2a is new L2;
24.--  Low (inherited from explicit)
25.
26.package Inner is
27.   type H3 is record
28.  --  High from outer config pragma
29.  a : Integer;
30.   end record;
31.   for H3 use record
32.  a at 0 range 0 .. 31;
33.   end record;
34.
35.   pragma Default_Scalar_Storage_Order
36.(Low_Order_First);
37.
38.   type L4 is record
39.  -- Low from inner default
40.  a : Integer;
41.   end record;
42.   for L4 use record
43.  a at 0 range 0 .. 31;
44.   end record;
45.end Inner;
46.
47.type H4a is new Inner.L4;
48.--  High from config pragma
49.--  No inheritance of default setting
50.
51.type H5 is record
52.   --  High from config pragma
53.   a : Integer;
54.end record;
55.for H5 use record
56.   a at 0 range 0 .. 31;
57.end record;
58. end DSSO1;

If this is compiled with -gnatR and we select the lines that mention
scalar storage order, we get:

for H1'Scalar_Storage_Order use System.High_Order_First;
for L2'Scalar_Storage_Order use System.Low_Order_First;
for L2A'Scalar_Storage_Order use System.Low_Order_First;
for INNER.H3'Scalar_Storage_Order use System.High_Order_First;
for INNER.L4'Scalar_Storage_Order use System.Low_Order_First;
for H4A'Scalar_Storage_Order use System.High_Order_First;
for H5'Scalar_Storage_Order use System.High_Order_First;

If the pragma is used in a configuration pragmas file, then the
binder will require that all units, including all run-time library
units, be compiled the same way (with a pragma in a configuration
pragma file with matching order). Given the following file:

 1. with DSSO1;
 2. procedure DSSOm is
 3.type R is record
 4.   N : Integer;
 5.end record;
 6.for R use record
 7.   N at 0 range 0 .. 31;
 8.end record;
 9. begin
10.null;
11. end;

If we compile DSSom with a configuration file containing a
pragma specifying Low_Order_First, and then compile DSSO1
with a configuration file containing a pragma specifying
High_Order_First, and then do a bind operation, we get
something like (exactly list of run-time files may vary):

error: files not compiled with same Default_Scalar_Storage_Order

files compiled with High_Order_First
  dssom.adb

files compiled with Low_Order_First
  dsso1.ads

files compiled with no Default_Scalar_Storage_Order
  s-stalib.adb
  system.ads
  s-memory.adb
  ada.ads
  a-except.adb
  a-elchha.adb
  s-soflin.adb
  s-parame.adb
  s-secsta.adb
  s-stoele.adb
  s-stache.adb
  s-exctab.adb
  s-except.adb
  s-excmac.ads
  s-excdeb.adb
  s-imgint.adb
  interfac.ads
  s-assert.adb
  s-traceb.adb
  s-wchcon.adb
  s-wchstw.adb
  s-wchcnv.adb
  s-wchjis.adb
  s-traent.adb

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

2014-07-29  Robert Dewar  de...@adacore.com

* ali.adb (Initialize_ALI): Initialize SSO_Default_Specified
(Scan_ALI): Set SSO_Default in ALIs_Record (Scan_ALI): Set
SSO_Default_Specified.
* ali.ads (ALIs_Record): Add field SSO_Default
(SSO_Default_Specified): New global switch.
* bcheck.adb (Check_Consistent_SSO_Default): New procedure
(Check_Configuration_Consistency): Call this procedure
* einfo.adb (SSO_Set_High_By_Default): New
function (SSO_Set_Low_By_Default): New function
(Set_SSO_Set_High_By_Default): New procedure
(Set_SSO_Set_Low_By_Default): New procedure (Write_Entity_Flags):
List new flags
* einfo.ads (SSO_Set_Low_By_Default): New flag
(SSO_Set_High_By_Default): New flag
* freeze.adb (Set_SSO_From_Default): New procedure

[Ada] Fix problem with Error arg for Unevaluated_Use_Of_Old

2014-07-29 Thread Arnaud Charlet
The Error option for pragma Unevaluated_Use_Of_Old was not properly
recognized, due to an internal problem with the generation of the
names table for the Snames package. This is now corrected, and
the following program compiles as shown with -gnatld7 -gnatj60:

 1. package Uneval_Old is
 2.pragma Unevaluated_Use_Of_Old (Error);
 3.function F (X : Integer) return Integer;
 4.procedure P (X : in out Integer) with
 5.  Post = (if X  0 then X = F(X)'Old + 1);
|
 prefix of attribute Old that is potentially
unevaluated must denote an entity

 6. end Uneval_Old;

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

2014-07-29  Robert Dewar  de...@adacore.com

* snames.ads-tmpl: Minor reformatting.
* xsnamest.adb (XSnamesT): Remove special casing of Name_Error
to give Error.  Not clear why this was there, but the compiler
sources do not reference Name_Error, and this interfered with
the circuits for pragma Unevaluated_Use_Of_Old.

Index: xsnamest.adb
===
--- xsnamest.adb(revision 213156)
+++ xsnamest.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 1992-2012, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -255,10 +255,6 @@
Name0 := 'O'  Translate (Name0, Lower_Case_Map);
 end if;
 
-if Name0 = error then
-   Name0 := V (error);
-end if;
-
 if not Match (Name0, Chk_Low) then
Put_Line (OutB,Name0  # );
 end if;
Index: snames.ads-tmpl
===
--- snames.ads-tmpl (revision 213160)
+++ snames.ads-tmpl (working copy)
@@ -56,8 +56,8 @@
 
--  First we have the one character names used to optimize the lookup
--  process for one character identifiers (to avoid the hashing in this
-   --  case) There are a full 256 of these, but only the entries for lower case
-   --  and upper case letters have identifiers
+   --  case) There are a full 256 of these, but only the entries for lower
+   --  case and upper case letters have identifiers
 
--  The lower case letter entries are used for one character identifiers
--  appearing in the source, for example in pragma Interface (C).


[Ada] Implement SPARK RM C.6 rules

2014-07-29 Thread Arnaud Charlet
This patch implements the following set of rules related to shared variables:

   1. A volatile representation aspect may only be applied to an
  object_declaration or a full_type_declaration.
   2. A component of a non-volatile type declaration shall not be volatile.
   3. A discriminant shall not be volatile.
   4. Neither a discriminated type nor an object of such a type shall be
  volatile.
   5. Neither a tagged type nor an object of such a type shall be volatile.
   6. A volatile variable shall only be declared at library-level.


-- Source --


--  shared_vars.ads

package Shared_Vars with SPARK_Mode = On is
   type T is new Integer with Volatile; -- OK
   type Colour is (Red, Green, Blue) with Volatile; -- OK
   S : Integer with Volatile; -- OK

   type R is record
  F1 : Integer;
  F2 : Integer with Volatile; -- illegal, SPARK RM C.6(1)
  F3 : Boolean;
   end record;

   type R2 is record
  F1 : Integer;
  F2 : T; -- illegal, SPARK RM C.6(2)
   end record;

   type R3 (D : Colour) is record -- illegal, SPARK RM C.6(3)
  Intensity : Natural;
   end record;

   type R4 (D : Boolean) is record
  F1 : Integer;
   end record with Volatile; -- illegal, SPARK RM C.6(4)

   type R5 (D : Boolean := False) is record
  F1 : Integer;
   end record;

   SV : R5 with Volatile; -- illegal, SPARK RM C.6(4)

   type R6 is tagged record
  F1 : Integer;
   end record with Volatile; -- illegal, SPARK RM C.6(5)

   type R7 is tagged record
  F1 : Integer;
   end record; 

   SV2 : R7 with Volatile; -- illegal, SPARK RM C.6(5)
end Shared_Vars;


-- Compilation and output --


$ gcc -c shared_vars.ads
hared_vars.ads:8:25: entity for aspect Volatile must denote a full type or
  object declaration
shared_vars.ads:14:07: component F2 of non-volatile type R2 cannot be
  volatile
shared_vars.ads:17:13: discriminant cannot be volatile
shared_vars.ads:21:09: discriminated type R4 cannot be volatile
shared_vars.ads:29:04: discriminated object SV cannot be volatile
shared_vars.ads:31:09: tagged type R6 cannot be volatile
shared_vars.ads:39:04: tagged object SV2 cannot be volatile

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

2014-07-29  Hristian Kirtchev  kirtc...@adacore.com

* freeze.adb (Freeze_Record_Type): Perform various
volatility-related checks.

Index: freeze.adb
===
--- freeze.adb  (revision 213169)
+++ freeze.adb  (working copy)
@@ -3411,6 +3411,43 @@
 end if;
  end if;
 
+ --  The following checks are only relevant when SPARK_Mode is on as
+ --  they are not standard Ada legality rules.
+
+ if SPARK_Mode = On then
+if Is_SPARK_Volatile (Rec) then
+
+   --  A discriminated type cannot be volatile (SPARK RM C.6(4))
+
+   if Has_Discriminants (Rec) then
+  Error_Msg_N (discriminated type  cannot be volatile, Rec);
+
+   --  A tagged type cannot be volatile (SPARK RM C.6(5))
+
+   elsif Is_Tagged_Type (Rec) then
+  Error_Msg_N (tagged type  cannot be volatile, Rec);
+   end if;
+
+--  A non-volatile record type cannot contain volatile components
+--  (SPARK RM C.6(2))
+
+else
+   Comp := First_Component (Rec);
+   while Present (Comp) loop
+  if Comes_From_Source (Comp)
+and then Is_SPARK_Volatile (Etype (Comp))
+  then
+ Error_Msg_Name_1 := Chars (Rec);
+ Error_Msg_N
+   (component  of non-volatile type % cannot be 
+ volatile, Comp);
+  end if;
+
+  Next_Component (Comp);
+   end loop;
+end if;
+ end if;
+
  --  All done if not a full record definition
 
  if Ekind (Rec) /= E_Record_Type then


[Ada] Out parameters of a null-excluding access type in entries.

2014-07-29 Thread Arnaud Charlet
If a procedure or entry has an formal out-parameter of a null-excluding access
type, there is no check applied to the actual before the call. This patch
removes a spurious access check on such parameters on entry calls.

Compiling and executing p.adb must yield;

Procedure version did not raise exception
Entry version did not raise exception

---
with Ada.Text_IO; use Ada.Text_IO;
procedure P is
   type Integer_Access is access all Integer;

   An_Integer : aliased Integer;

   procedure Procedure_Version (A : out not null Integer_Access) is
   begin
  A := An_Integer'Access;
   end Procedure_Version;

   protected Object is
  entry Entry_Version (A : out not null Integer_Access);
   end Object;

   protected body Object is
  entry Entry_Version (A : out not null Integer_Access) when True is
 Junk : integer := 0;
  begin
 A := An_Integer'Access;
  end Entry_Version;
   end Object;

   A : Integer_Access;
begin
   A := null;
   Procedure_Version (A);
   Put_Line (Procedure version did not raise exception);

   A := null;
   Object.Entry_Version (A);
   Put_Line (Entry version did not raise exception);
end;

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

2014-07-29  Ed Schonberg  schonb...@adacore.com

* exp_ch5.adb (Expand_N_Assignment_Statement): If the target type
is a null-excluding access type, do not generate a constraint
check if Suppress_Assignment_Checks is set on assignment node.
* exp_ch9.adb (Build_Simple_Entry_Call): If actual is an out
parameter of a null-excluding access type, there is access check
on entry, so set Suppress_Assignment_Checks on generated statement
that assigns actual to parameter block.
* sinfo.ads: Document additional use of Suppress_Assignment_Checks.

Index: exp_ch5.adb
===
--- exp_ch5.adb (revision 213163)
+++ exp_ch5.adb (working copy)
@@ -2001,6 +2001,7 @@
   if Is_Access_Type (Typ)
 and then Can_Never_Be_Null (Etype (Lhs))
 and then not Can_Never_Be_Null (Etype (Rhs))
+and then not Suppress_Assignment_Checks (N)
   then
  Apply_Constraint_Check (Rhs, Etype (Lhs));
   end if;
Index: sinfo.ads
===
--- sinfo.ads   (revision 213194)
+++ sinfo.ads   (working copy)
@@ -2052,7 +2052,9 @@
--and range checks in cases where the generated code knows that the
--value being assigned is in range and satisfies any predicate. Also
--can be set in N_Object_Declaration nodes, to similarly suppress any
-   --checks on the initializing value.
+   --checks on the initializing value. In assignment statements it also
+   --suppresses access checks in the generated code for out- and in-out
+   --parameters in entry calls.
 
--  Suppress_Loop_Warnings (Flag17-Sem)
--Used in N_Loop_Statement node to indicate that warnings within the
Index: exp_ch9.adb
===
--- exp_ch9.adb (revision 213159)
+++ exp_ch9.adb (working copy)
@@ -4755,7 +4755,8 @@
   --  case of limited type. We cannot assign it unless the
   --  Assignment_OK flag is set first. An out formal of an
   --  access type must also be initialized from the actual,
-  --  as stated in RM 6.4.1 (13).
+  --  as stated in RM 6.4.1 (13), but no constraint is applied
+  --  before the call.
 
   if Ekind (Formal) /= E_Out_Parameter
 or else Is_Access_Type (Etype (Formal))
@@ -4767,6 +4768,7 @@
Make_Assignment_Statement (Loc,
  Name = N_Var,
  Expression = Relocate_Node (Actual)));
+ Set_Suppress_Assignment_Checks (Last (Stats));
   end if;
 
   Append (N_Node, Decls);


[Ada] PR ada/60652 - Wrong value for System.OS_Constants.CRTSCTS

2014-07-29 Thread Arnaud Charlet
On Linux, s-oscons-tmplt.c needs to define _BSD_SOURCE in order for
CRTSCTS to be visible. Otherwise the macro is undefined, and defaulted
to -1.

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

2014-07-29  Thomas Quinot  qui...@adacore.com

PR ada/60652
* s-oscons-tmplt.c: For Linux, define _BSD_SOURCE in order for
CRTSCTS to be visible.

Index: s-oscons-tmplt.c
===
--- s-oscons-tmplt.c(revision 213156)
+++ s-oscons-tmplt.c(working copy)
@@ -86,11 +86,18 @@
  ** a number of non-POSIX but useful/required features.
  **/
 
-#if defined (__linux__)  !defined (_XOPEN_SOURCE)
-/* For Linux, define _XOPEN_SOURCE to get IOV_MAX */
-#define _XOPEN_SOURCE 500
-#endif
+#if defined (__linux__)
 
+/* Define _XOPEN_SOURCE to get IOV_MAX */
+# if !defined (_XOPEN_SOURCE)
+#  define _XOPEN_SOURCE 500
+# endif
+
+/* Define _BSD_SOURCE to get CRTSCTS */
+# define _BSD_SOURCE
+
+#endif /* defined (__linux__) */
+
 /* Include gsocket.h before any system header so it can redefine FD_SETSIZE */
 
 #include gsocket.h


[Ada] Selectively inline subprograms in GNATprove mode

2014-07-29 Thread Arnaud Charlet
For formal verification with GNATprove, frontend inlining can be used to
relieve users from the need to add contracts to local subprograms. Thus,
we adopt here a simple policy for inlining in GNATprove mode, which consists
in inlining all local subprograms which can be inlined, as soon as they
don't have a contract. This policy gives to the user the control over which
subprograms may be inlined.

This is under debug flag -gnatdQ for now, until remaining issues have been
fixed.

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

2014-07-29  Yannick Moy  m...@adacore.com

* debug.adb Enable GNATprove inlining under debug flag -gnatdQ for now.
* inline.ads, inline.adb (Can_Be_Inlined_In_GNATprove_Mode): New
function to decide when a subprogram can be inlined in GNATprove mode.
(Check_And_Build_Body_To_Inline): Include GNATprove_Mode as a
condition for possible inlining.
* sem_ch10.adb (Analyze_Compilation_Unit): Remove special case
for Inline_Always in GNATprove mode.
* sem_ch6.adb (Analyze_Subprogram_Body_Helper): Build inlined
body for subprograms in GNATprove mode, under debug flag -gnatdQ.
* sem_prag.adb Minor change in comments.
* sem_res.adb (Resolve_Call): Only perform GNATprove inlining
inside subprograms marked as SPARK_Mode On.
* sinfo.ads Minor typo fix.

Index: sinfo.ads
===
--- sinfo.ads   (revision 213201)
+++ sinfo.ads   (working copy)
@@ -817,7 +817,7 @@
--set, it means that the front end can assure no overlap of operands.
 
--  Body_To_Inline (Node3-Sem)
-   --present in subprogram declarations. Denotes analyzed but unexpanded
+   --Present in subprogram declarations. Denotes analyzed but unexpanded
--body of subprogram, to be used when inlining calls. Present when the
--subprogram has an Inline pragma and inlining is enabled. If the
--declaration is completed by a renaming_as_body, and the renamed en-
Index: inline.adb
===
--- inline.adb  (revision 213201)
+++ inline.adb  (working copy)
@@ -44,8 +44,10 @@
 with Sem_Ch10; use Sem_Ch10;
 with Sem_Ch12; use Sem_Ch12;
 with Sem_Eval; use Sem_Eval;
+with Sem_Prag; use Sem_Prag;
 with Sem_Util; use Sem_Util;
 with Sinfo;use Sinfo;
+with Sinput;   use Sinput;
 with Snames;   use Snames;
 with Stand;use Stand;
 with Uname;use Uname;
@@ -1257,12 +1259,13 @@
  end if;
   end if;
 
-  --  We do not inline a subprogram  that is too large, unless it is
-  --  marked Inline_Always. This pragma does not suppress the other
-  --  checks on inlining (forbidden declarations, handlers, etc).
+  --  We do not inline a subprogram that is too large, unless it is marked
+  --  Inline_Always or we are in GNATprove mode. This pragma does not
+  --  suppress the other checks on inlining (forbidden declarations,
+  --  handlers, etc).
 
   if Stat_Count  Max_Size
-and then not Has_Pragma_Inline_Always (Subp)
+and then not (Has_Pragma_Inline_Always (Subp) or else GNATprove_Mode)
   then
  Cannot_Inline (cannot inline (body too large)?, N, Subp);
  return;
@@ -1454,6 +1457,152 @@
   end if;
end Cannot_Inline;
 
+   --
+   -- Can_Be_Inlined_In_GNATprove_Mode --
+   --
+
+   function Can_Be_Inlined_In_GNATprove_Mode
+ (Spec_Id : Entity_Id;
+  Body_Id : Entity_Id) return Boolean
+   is
+  function Has_Some_Contract (Id : Entity_Id) return Boolean;
+  --  Returns True if subprogram Id has any contract (Pre, Post, Global,
+  --  Depends, etc.)
+
+  function In_Some_Private_Part (N : Node_Id) return Boolean;
+  --  Returns True if node N is defined in the private part of a package
+
+  function In_Unit_Body (N : Node_Id) return Boolean;
+  --  Returns True if node N is defined in the body of a unit
+
+  function Is_Expression_Function (Id : Entity_Id) return Boolean;
+  --  Returns True if subprogram Id was defined originally as an expression
+  --  function.
+
+  ---
+  -- Has_Some_Contract --
+  ---
+
+  function Has_Some_Contract (Id : Entity_Id) return Boolean is
+ Items : constant Node_Id := Contract (Id);
+  begin
+ return Present (Items)
+   and then (Present (Pre_Post_Conditions (Items))
+   or else
+ Present (Contract_Test_Cases (Items))
+   or else
+ Present (Classifications (Items)));
+  end Has_Some_Contract;
+
+  --
+  -- In_Some_Private_Part --
+  --
+
+  function In_Some_Private_Part (N : Node_Id) return Boolean is
+ P  : Node_Id := N;
+  

[Ada] Apply proper predicate tests to OUT and IN OUT parameters

2014-07-29 Thread Arnaud Charlet
This fix is inspired by ACATS test C324002, which tests that
predicate tests for OUT and IN OUT parameters are properly
applied. They were missed in some cases, and applied when
they should not be to Finalize procedures.

The following three tests (cutdown versions of C324002) compile
and execute quietly:

 1. with Ada.Assertions; use Ada.Assertions;
 2. procedure PredByRef1 is
 3.pragma Assertion_Policy (Check);
 4.type R is tagged record
 5.   X : Integer;
 6.end record
 7.with Dynamic_Predicate = R.X mod 2 = 0;
 8.
 9.RV : R := (X = 0);
10.
11.procedure P (Arg : in out R) is
12.begin
13.   Arg.X := Arg.X + 1;
14.end;
15.
16. begin
17.P (RV);
18.raise Program_Error;
19. exception
20.when Assertion_Error = null;
21. end PredByRef1;

 1. with Ada.Assertions; use Ada.Assertions;
 2. with Ada.Finalization; use Ada.Finalization;
 3. procedure PredByRef2 is
 4.pragma Assertion_Policy (Check);
 5.type R is new Controlled with record
 6.   X : Integer := 0;
 7.end record
 8.with Dynamic_Predicate = R.X mod 2 = 0;
 9.
10.RV : R;
11.
12.procedure P (Arg : in out R) is
13.begin
14.   Arg.X := Arg.X + 1;
15.end;
16.
17. begin
18.P (RV);
19.raise Program_Error;
20. exception
21.when Assertion_Error = null;
22. end PredByRef2;

 1. with Ada.Finalization;
 2. with Ada.Assertions; use Ada.Assertions;
 3. procedure PredByRef3 is
 4.pragma Assertion_Policy (Check);
 5.type String_Access is access all String;
 6.
 7.type Unbounded_String is new
 8.  Ada.Finalization.Controlled with record
 9.   Length : Natural := 100;
10.end record;
11.
12.subtype Max_10_Char_String is Unbounded_String
13.   with Dynamic_Predicate =
14.  Max_10_Char_String.Length = 10;
15.
16.procedure Set_Unbounded_String
17.  (Target : out Unbounded_String) is
18.begin
19.   Target.Length := 200;
20.end Set_Unbounded_String;
21.
22.Our_Data : array (1 .. 10) of Max_10_Char_String
23. begin
24.Set_Unbounded_String (Our_Data(6));
25.raise Program_Error;
26. exception
27.when Assertion_Error = null;
28. end PredByRef3;

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

2014-07-29  Robert Dewar  de...@adacore.com

* exp_ch6.adb (Add_Call_By_Copy_Code): Minor reformatting
(Expand_Actuals): Make sure predicate checks are properly applied
for the case of OUT or IN OUT parameters.
* sem_res.adb: Minor reformatting (Resolve_Actuals): Skip
predicate tests on arguments for Finalize
* sem_util.adb (No_Predicate_Test_On_Arguments): Returns True
if predicate tests on subprogram arguments should be skipped.
* sem_util.ads (No_Predicate_Test_On_Arguments): New function

Index: sem_util.adb
===
--- sem_util.adb(revision 213208)
+++ sem_util.adb(working copy)
@@ -13785,6 +13785,44 @@
   Actual_Id := Next_Actual (Actual_Id);
end Next_Actual;
 
+   
+   -- No_Predicate_Test_On_Arguments --
+   
+
+   function No_Predicate_Test_On_Arguments (Subp : Entity_Id) return Boolean is
+   begin
+  --  Do not test predicates on call to generated default Finalize, since
+  --  we are not interested in whether something we are finalizing (and
+  --  typically destroying) satisfies its predicates.
+
+  if Chars (Subp) = Name_Finalize
+and then not Comes_From_Source (Subp)
+  then
+ return True;
+
+  --  Do not test predicates on call to Init_Proc, since if needed the
+  --  predicate test will occur at some other point.
+
+  elsif Is_Init_Proc (Subp) then
+ return True;
+
+  --  Do not test predicates on call to predicate function, since this
+  --  would cause infinite recursion.
+
+  elsif Ekind (Subp) = E_Function
+and then (Is_Predicate_Function (Subp)
+or else
+  Is_Predicate_Function_M (Subp))
+  then
+ return True;
+
+  --  For now, no other cases
+
+  else
+ return False;
+  end if;
+   end No_Predicate_Test_On_Arguments;
+
-
-- No_Scalar_Parts --
-
Index: sem_util.ads
===
--- sem_util.ads(revision 213206)
+++ sem_util.ads(working copy)
@@ -1582,6 +1582,11 @@
--  Note that the result produced is always an expression, not a parameter
--  association node, even if named notation was used.
 
+   function 

[Ada] Small cleanup in array aggregate handling code

2014-07-29 Thread Arnaud Charlet
This removes a subprogram which serves no useful purpose and changes the
affected case to use the common code path.  No functional changes.

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

2014-07-29  Eric Botcazou  ebotca...@adacore.com

* exp_aggr.adb (Safe_Slice_Assignment): Remove.
(Expand_Array_Aggregate): For a safe slice assignment, just set
the target and use the common code path.

Index: exp_aggr.adb
===
--- exp_aggr.adb(revision 213201)
+++ exp_aggr.adb(working copy)
@@ -289,11 +289,6 @@
--  If this transformation is not possible, N is unchanged and False is
--  returned.
 
-   function Safe_Slice_Assignment (N : Node_Id) return Boolean;
-   --  If a slice assignment has an aggregate with a single others_choice,
-   --  the assignment can be done in place even if bounds are not static,
-   --  by converting it into a loop over the discrete range of the slice.
-
function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean;
--  If the type of the aggregate is a two-dimensional bit_packed array
--  it may be transformed into an array of bytes with constant values,
@@ -404,8 +399,8 @@
   elsif Restriction_Active (No_Elaboration_Code)
 or else Restriction_Active (No_Implicit_Loops)
 or else Is_Two_Dim_Packed_Array (Typ)
-or else ((Ekind (Current_Scope) = E_Package
- and then Static_Elaboration_Desired (Current_Scope)))
+or else (Ekind (Current_Scope) = E_Package
+   and then Static_Elaboration_Desired (Current_Scope))
   then
  Max_Aggr_Size := 2 ** 24;
 
@@ -443,9 +438,7 @@
  --  is an object declaration with non-static bounds it will trip gcc;
  --  such an aggregate must be expanded into a single assignment.
 
- if Hiv = Lov
-   and then Nkind (Parent (N)) = N_Object_Declaration
- then
+ if Hiv = Lov and then Nkind (Parent (N)) = N_Object_Declaration then
 declare
Index_Type : constant Entity_Id :=
  Etype
@@ -454,8 +447,8 @@
 
 begin
if not Compile_Time_Known_Value (Type_Low_Bound (Index_Type))
-  or else not Compile_Time_Known_Value
-(Type_High_Bound (Index_Type))
+ or else not Compile_Time_Known_Value
+   (Type_High_Bound (Index_Type))
then
   if Present (Component_Associations (N)) then
  Indx :=
@@ -603,7 +596,7 @@
 --  Recursion to following indexes for multiple dimension case
 
 if Present (Next_Index (Index))
-   and then not Component_Check (Expr, Next_Index (Index))
+  and then not Component_Check (Expr, Next_Index (Index))
 then
return False;
 end if;
@@ -653,11 +646,11 @@
   end if;
 
   --  Checks 5 (if the component type is tagged, then we may need to do
-  --tag adjustments. Perhaps this should be refined to check for any
-  --component associations that actually need tag adjustment, similar
-  --to the test in Component_Not_OK_For_Backend for record aggregates
-  --with tagged components, but not clear whether it's worthwhile ???;
-  --in the case of the JVM, object tags are handled implicitly)
+  --  tag adjustments. Perhaps this should be refined to check for any
+  --  component associations that actually need tag adjustment, similar
+  --  to the test in Component_Not_OK_For_Backend for record aggregates
+  --  with tagged components, but not clear whether it's worthwhile ???;
+  --  in the case of the JVM, object tags are handled implicitly)
 
   if Is_Tagged_Type (Component_Type (Typ))
 and then Tagged_Type_Expansion
@@ -934,7 +927,8 @@
 end case;
 
 if Local_Compile_Time_Known_Value (Low)
-  and then Local_Compile_Time_Known_Value (High)
+ and then
+   Local_Compile_Time_Known_Value (High)
 then
Is_Empty :=
  UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
@@ -956,7 +950,8 @@
 return True;
 
  elsif Local_Compile_Time_Known_Value (L)
-   and then Local_Compile_Time_Known_Value (H)
+ and then
+   Local_Compile_Time_Known_Value (H)
  then
 return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
  end if;
@@ -1053,9 +1048,7 @@
 Expr_Q := Expr;
  end if;
 
- if Present (Etype (N))
-   and then Etype (N) /= Any_Composite
- then
+ if Present (Etype (N)) and then Etype (N) /= Any_Composite then
 Comp_Type := Component_Type (Etype (N));
 pragma Assert (Comp_Type = Ctype); --  

[Ada] Internal cleanup for Predicate_Tests_On_Arguments

2014-07-30 Thread Arnaud Charlet
Some additional cases of internal routines are now detected and skip
predicate tests on arguments. Not clear if this fixes additional
problems or not, but it is certainly a desirable change. No further
test required.

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

2014-07-30  Robert Dewar  de...@adacore.com

* sem_util.adb (Predicate_Tests_On_Arguments): Omit tests for
some additional cases of internally generated routines.

Index: sem_util.adb
===
--- sem_util.adb(revision 213212)
+++ sem_util.adb(working copy)
@@ -14723,32 +14723,42 @@
 
function Predicate_Tests_On_Arguments (Subp : Entity_Id) return Boolean is
begin
+  --  Always test predicates on indirect call
+
+  if Ekind (Subp) = E_Subprogram_Type then
+ return True;
+
   --  Do not test predicates on call to generated default Finalize, since
   --  we are not interested in whether something we are finalizing (and
   --  typically destroying) satisfies its predicates.
 
-  if Chars (Subp) = Name_Finalize
+  elsif Chars (Subp) = Name_Finalize
 and then not Comes_From_Source (Subp)
   then
  return False;
 
- --  Do not test predicates on call to Init_Proc, since if needed the
- --  predicate test will occur at some other point.
+  --  Do not test predicates on any internally generated routines
 
+  elsif Is_Internal_Name (Chars (Subp)) then
+ return False;
+
+  --  Do not test predicates on call to Init_Proc, since if needed the
+  --  predicate test will occur at some other point.
+
   elsif Is_Init_Proc (Subp) then
  return False;
 
- --  Do not test predicates on call to predicate function, since this
- --  would cause infinite recursion.
+  --  Do not test predicates on call to predicate function, since this
+  --  would cause infinite recursion.
 
   elsif Ekind (Subp) = E_Function
 and then (Is_Predicate_Function (Subp)
-  or else
+or else
   Is_Predicate_Function_M (Subp))
   then
  return False;
 
- --  For now, no other exceptions
+  --  For now, no other exceptions
 
   else
  return True;


[Ada] Inheritance of variables in extending projects

2014-07-30 Thread Arnaud Charlet
A variable V declared in a project A that is extended by a project B is
now inherited in project B; it can be referenced as V in project B or as
B.V in any other project that imports B.

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

2014-07-30  Vincent Celier  cel...@adacore.com

* prj-proc.adb (Imported_Or_Extended_Project_From): New Boolean
parameter No_Extending, defaulted to False. When No_Extending
is True, do not look for an extending project.
(Expression): For a variable reference that is not for the current
project, get its Id calling Imported_Or_Extended_Project_From
with No_Extending set to True.
* prj-strt.adb (Parse_Variable_Reference): If a referenced
variable is not found in the current project, check if it is
defined in one of the projects it extends.

Index: prj-proc.adb
===
--- prj-proc.adb(revision 213201)
+++ prj-proc.adb(working copy)
@@ -118,8 +118,9 @@
--  of an expression and return it as a Variable_Value.
 
function Imported_Or_Extended_Project_From
- (Project   : Project_Id;
-  With_Name : Name_Id) return Project_Id;
+ (Project  : Project_Id;
+  With_Name: Name_Id;
+  No_Extending : Boolean := False) return Project_Id;
--  Find an imported or extended project of Project whose name is With_Name
 
function Package_From
@@ -705,8 +706,9 @@
  The_Name :=
Name_Of (Term_Project, From_Project_Node_Tree);
  The_Project := Imported_Or_Extended_Project_From
-  (Project   = Project,
-   With_Name = The_Name);
+  (Project  = Project,
+   With_Name= The_Name,
+   No_Extending = True);
   end if;
 
   if Present (Term_Package) then
@@ -1261,8 +1263,9 @@
---
 
function Imported_Or_Extended_Project_From
- (Project   : Project_Id;
-  With_Name : Name_Id) return Project_Id
+ (Project  : Project_Id;
+  With_Name: Name_Id;
+  No_Extending : Boolean := False) return Project_Id
is
   List: Project_List;
   Result  : Project_Id;
@@ -1304,7 +1307,12 @@
 Proj := Result.Extends;
 while Proj /= No_Project loop
if Proj.Name = With_Name then
-  Temp_Result := Result;
+  if No_Extending then
+ Temp_Result := Proj;
+  else
+ Temp_Result := Result;
+  end if;
+
   exit;
end if;
 
Index: prj-strt.adb
===
--- prj-strt.adb(revision 213201)
+++ prj-strt.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 2001-2010, Free Software Foundation, Inc. --
+--  Copyright (C) 2001-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1162,7 +1162,7 @@
 
 --  If we have not found the variable in the package, check if the
 --  variable has been declared in the project, or in any of its
---  ancestors.
+--  ancestors, or in any of the project it extends.
 
 if No (Current_Variable) then
declare
@@ -1182,8 +1182,15 @@
 
  exit when Present (Current_Variable);
 
- Proj := Parent_Project_Of (Proj, In_Tree);
+ if No (Parent_Project_Of (Proj, In_Tree)) then
+Proj :=
+  Extended_Project_Of
+(Project_Declaration_Of (Proj, In_Tree), In_Tree);
 
+ else
+Proj := Parent_Project_Of (Proj, In_Tree);
+ end if;
+
  Set_Project_Node_Of (Variable, In_Tree, To = Proj);
 
  exit when No (Proj);


[Ada] Improve run time performance for large array reset

2014-07-30 Thread Arnaud Charlet
This patch makes the compiler generate faster code to reset a large array of
integers to 0 by means of an aggregate with a single Others choice and, more
generally, to set a large array of storage units to a single value by the
same means, for example:

  type Arr is array (1 .. 1) of Integer;
  A : Arr := (others = 0);

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

2014-07-30  Eric Botcazou  ebotca...@adacore.com

* exp_aggr.adb (Aggr_Assignment_OK_For_Backend): New predicate.
(Expand_Array_Aggregate): Also enable in-place expansion for
code generated by the compiler.  For an object declaration,
set the kind of the object in addition to its type.  If an
in-place assignment is to be generated and it can be directly
done by the back-end, do not expand the aggregate.
* fe.h (Is_Others_Aggregate): Declare.
* gcc-interface/trans.c
(gnat_to_gnu) N_Assignment_Statement: Add support for an
aggregate with a single Others choice on the RHS by means of
__builtin_memset.  Tidy up.

Index: fe.h
===
--- fe.h(revision 213201)
+++ fe.h(working copy)
@@ -202,6 +202,11 @@
 extern void Check_Elaboration_Code_Allowed (Node_Id);
 extern void Check_Implicit_Dynamic_Code_Allowed (Node_Id);
 
+/* sem_aggr:  */
+#define Is_Others_Aggregatesem_aggr__is_others_aggregate
+
+extern Boolean Is_Others_Aggregate (Node_Id);
+
 /* sem_aux:  */
 
 #define Ancestor_Subtype   sem_aux__ancestor_subtype
Index: exp_aggr.adb
===
--- exp_aggr.adb(revision 213216)
+++ exp_aggr.adb(working copy)
@@ -3945,6 +3945,9 @@
   Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
   --  The type of each index
 
+  In_Place_Assign_OK_For_Declaration : Boolean := False;
+  --  True if we are to generate an in place assignment for a declaration
+
   Maybe_In_Place_OK : Boolean;
   --  If the type is neither controlled nor packed and the aggregate
   --  is the expression in an assignment, assignment in place may be
@@ -3955,6 +3958,9 @@
   --  If Others_Present (J) is True, then there is an others choice
   --  in one of the sub-aggregates of N at dimension J.
 
+  function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean;
+  --  Returns true if an aggregate assignment can be done by the back end
+
   procedure Build_Constrained_Type (Positional : Boolean);
   --  If the subtype is not static or unconstrained, build a constrained
   --  type using the computable sizes of the aggregate and its sub-
@@ -3991,6 +3997,108 @@
   --  built directly into the target of the assignment it must be free
   --  of side-effects.
 
+  
+  -- Aggr_Assignment_OK_For_Backend --
+  
+
+  --  Backend processing by Gigi/gcc is possible only if all the following
+  --  conditions are met:
+
+  --1. N consists of a single OTHERS choice, possibly recursively
+
+  --2. The component type is discrete
+
+  --3. The component size is a multiple of Storage_Unit
+
+  --4. The component size is exactly Storage_Unit or the expression is
+  --   an integer whose unsigned value is the binary concatenation of
+  --   K times its remainder modulo 2**Storage_Unit.
+
+  --  The ultimate goal is to generate a call to a fast memset routine
+  --  specifically optimized for the target.
+
+  function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean is
+ Ctyp  : Entity_Id;
+ Expr  : Node_Id := N;
+ Remainder : Uint;
+ Value : Uint;
+ Nunits: Nat;
+
+  begin
+ --  Recurse as far as possible to find the innermost component type
+
+ Ctyp := Etype (N);
+ while Is_Array_Type (Ctyp) loop
+if Nkind (Expr) /= N_Aggregate
+  or else not Is_Others_Aggregate (Expr)
+then
+   return False;
+end if;
+
+Expr := Expression (First (Component_Associations (Expr)));
+
+for J in 1 .. Number_Dimensions (Ctyp) - 1 loop
+   if Nkind (Expr) /= N_Aggregate
+ or else not Is_Others_Aggregate (Expr)
+   then
+  return False;
+   end if;
+
+   Expr := Expression (First (Component_Associations (Expr)));
+end loop;
+
+Ctyp := Component_Type (Ctyp);
+ end loop;
+
+ if not Is_Discrete_Type (Ctyp)
+   or else RM_Size (Ctyp) mod System_Storage_Unit /= 0
+ then
+return False;
+ end if;
+
+ --  The expression needs to be analyzed if True is returned
+
+ Analyze_And_Resolve (Expr, Ctyp);
+
+  

[Ada] New unit GNAT.Formatted_String providing C/C++ format string support

2014-07-30 Thread Arnaud Charlet
The following code:

  with Ada.Text_IO;   use Ada.Text_IO;
  with GNAT.Formatted_String; use GNAT.Formatted_String;

  procedure Fout is
 F  : Formatted_String := +%c %% %#08x;
 Vc : Character := 'v';
 Vi : Integer := 12;
  begin
 F := F  Vc  Vi;
 Put_Line (-F);
  end Fout;

Should output:

   v % 0x0c

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

2014-07-30  Pascal Obry  o...@adacore.com

* g-forstr.adb, g-forstr.ads: New.
* gnat_rm.texi, impunit.adb Makefile.rtl: Add new unit
GNAT.Formatted_String.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 213240)
+++ gnat_rm.texi(working copy)
@@ -594,6 +594,7 @@
 * GNAT.Expect (g-expect.ads)::
 * GNAT.Expect.TTY (g-exptty.ads)::
 * GNAT.Float_Control (g-flocon.ads)::
+* GNAT.Formatted_String (g-forstr.ads)::
 * GNAT.Heap_Sort (g-heasor.ads)::
 * GNAT.Heap_Sort_A (g-hesora.ads)::
 * GNAT.Heap_Sort_G (g-hesorg.ads)::
@@ -18934,6 +18935,7 @@
 * GNAT.Expect (g-expect.ads)::
 * GNAT.Expect.TTY (g-exptty.ads)::
 * GNAT.Float_Control (g-flocon.ads)::
+* GNAT.Formatted_String (g-forstr.ads)::
 * GNAT.Heap_Sort (g-heasor.ads)::
 * GNAT.Heap_Sort_A (g-hesora.ads)::
 * GNAT.Heap_Sort_G (g-hesorg.ads)::
@@ -19860,6 +19862,18 @@
 library calls may cause this mode to be modified, and the Reset procedure
 in this package can be used to reestablish the required mode.
 
+@node GNAT.Formatted_String (g-forstr.ads)
+@section @code{GNAT.Formatted_String} (@file{g-forstr.ads})
+@cindex @code{GNAT.Formatted_String} (@file{g-forstr.ads})
+@cindex Formatted String
+
+@noindent
+Provides support for C/C++ printf() formatted string. The format is
+copied from the printf() routine and should therefore gives identical
+output. Some generic routines are provided to be able to use types
+derived from Integer, Float or enumerations as values for the
+formatted string.
+
 @node GNAT.Heap_Sort (g-heasor.ads)
 @section @code{GNAT.Heap_Sort} (@file{g-heasor.ads})
 @cindex @code{GNAT.Heap_Sort} (@file{g-heasor.ads})
Index: impunit.adb
===
--- impunit.adb (revision 213201)
+++ impunit.adb (working copy)
@@ -273,6 +273,7 @@
 (g-expect, F),  -- GNAT.Expect
 (g-exptty, F),  -- GNAT.Expect.TTY
 (g-flocon, F),  -- GNAT.Float_Control
+(g-forstr, F),  -- GNAT.Formatted_String
 (g-heasor, F),  -- GNAT.Heap_Sort
 (g-hesora, F),  -- GNAT.Heap_Sort_A
 (g-hesorg, F),  -- GNAT.Heap_Sort_G
Index: Makefile.rtl
===
--- Makefile.rtl(revision 213201)
+++ Makefile.rtl(working copy)
@@ -411,6 +411,7 @@
   g-expect$(objext) \
   g-exptty$(objext) \
   g-flocon$(objext) \
+  g-forstr$(objext) \
   g-heasor$(objext) \
   g-hesora$(objext) \
   g-hesorg$(objext) \
Index: g-forstr.adb
===
--- g-forstr.adb(revision 0)
+++ g-forstr.adb(revision 0)
@@ -0,0 +1,951 @@
+--
+--  --
+-- GNAT COMPILER COMPONENTS --
+--  --
+--G N A T . F O R M A T T E D _ S T R I N G --
+--  --
+-- B o d y  --
+--  --
+-- Copyright (C) 2014, Free Software Foundation, Inc.   --
+--  --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+--  --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.   --
+--  --
+-- You should have received a copy of the GNU General Public License and--
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If 

[Ada] Illegal external aspects not detected

2014-07-30 Thread Arnaud Charlet
This patch modifies the categorization of aspects Async_Readers, Async_Writers,
Effective_Reads and Effective_Writes to no longer require delayed actions. This
in turn ensures that the analysis of their aspect form correctly creates their
pragma counterparts.


-- Source --


--  illegal_externals.ads

package Illegal_Externals with SPARK_Mode = On is
   type I  is range 1 .. 10 with Async_Readers;
   type I2 is range 1 .. 10 with Async_Readers = True; 
   type I3 is range 1 .. 10 with Async_Readers = False; 
   type T1 is array (I) of Integer with Volatile; 
   type T2 is array (I) of Integer
 with Volatile,
  Async_Readers= True, 
  Async_Writers= False,
  Effective_Writes = False,
  Effective_Reads  = False;
   subtype S1 is Integer range 1 .. 10 with Async_Readers; 
   subtype S2 is Integer range 1 .. 10 with Async_Readers = True; 
   subtype S3 is Integer range 1 .. 10 with Async_Readers = False; 
   procedure P1 
 with Import,
  Convention = C;
   procedure P2
 with Import,
  Async_Readers, 
  Convention = C;
end Illegal_Externals;


-- Compilation and output --


$ gcc -c illegal_externals.ads
illegal_externals.ads:2:34: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:3:34: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:4:34: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:8:11: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:9:11: aspect Async_Writers must apply to a volatile
  object
illegal_externals.ads:10:11: aspect Effective_Writes must apply to a volatile
  object
illegal_externals.ads:11:11: aspect Effective_Reads must apply to a volatile
  object
illegal_externals.ads:12:45: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:13:45: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:14:45: aspect Async_Readers must apply to a volatile
  object
illegal_externals.ads:20:11: aspect Async_Readers must apply to a volatile
  object

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

2014-07-30  Hristian Kirtchev  kirtc...@adacore.com

* aspects.ads Aspects Async_Readers, Async_Writers,
Effective_Reads and Effective_Writes do not need to be delayed.
* sem_ch13.adb (Analyze_Aspect_Specifications): Propagate the
optional Boolean expression when generating the corresponding
pragma for an external property aspect.
* sem_prag.adb (Analyze_External_Property_In_Decl_Part): Remove
local constant Obj. Add local constant Obj_Id. Reimplement the
check which ensures that the related variable is in fact volatile.
(Analyze_Pragma): Reimplement the analysis of external property pragmas.
* sem_util.adb (Is_Enabled): New routine.
(Variable_Has_Enabled_Property): Reimplement the detection of
an enabled external property.

Index: sem_prag.adb
===
--- sem_prag.adb(revision 213211)
+++ sem_prag.adb(working copy)
@@ -1834,29 +1834,28 @@
  (N: Node_Id;
   Expr_Val : out Boolean)
is
-  Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
-  Obj  : constant Node_Id := Get_Pragma_Arg (Arg1);
-  Expr : constant Node_Id := Get_Pragma_Arg (Next (Arg1));
+  Arg1   : constant Node_Id   := First (Pragma_Argument_Associations (N));
+  Obj_Id : constant Entity_Id := Entity (Get_Pragma_Arg (Arg1));
+  Expr   : constant Node_Id   := Get_Pragma_Arg (Next (Arg1));
 
begin
   Error_Msg_Name_1 := Pragma_Name (N);
 
-  --  The Async / Effective pragmas must apply to a volatile object other
-  --  than a formal subprogram parameter (SPARK RM 7.1.3(2)).
+  --  An external property pragma must apply to a volatile object other
+  --  than a formal subprogram parameter (SPARK RM 7.1.3(2)). The check
+  --  is performed at the end of the declarative region due to a possible
+  --  out-of-order arrangement of pragmas:
+  --
+  --Obj : ...;
+  --pragma Async_Readers (Obj);
+  --pragma Volatile (Obj);
 
-  if Is_SPARK_Volatile_Object (Obj) then
- if Is_Entity_Name (Obj)
-   and then Present (Entity (Obj))
-   and then Is_Formal (Entity (Obj))
- then
-SPARK_Msg_N (external property % cannot apply to parameter, N);
- end if;
-  else
+  if not Is_SPARK_Volatile (Obj_Id) then
  SPARK_Msg_N
(external property % must apply to a volatile object, N);
   end if;
 
-  --  Ensure that the expression (if present) is static Boolean. A missing
+  --  Ensure that the Boolean expression (if present) is static. A missing
   --  argument defaults the value 

[Ada] Add query function to distinguish code of inlining from instances

2014-07-30 Thread Arnaud Charlet
In GNATprove, we need to distinguish code form inlined subprograms and code
from generic instances, based on their source locations, to have better
messages. This new query does precisely this.

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

2014-07-30  Yannick Moy  m...@adacore.com

* sinput.ads, sinput.adb (Comes_From_Inlined_Body): New function that
returns True for source pointer for an inlined body.

Index: sinput.adb
===
--- sinput.adb  (revision 213201)
+++ sinput.adb  (working copy)
@@ -302,6 +302,17 @@
   end case;
end Check_For_BOM;
 
+   -
+   -- Comes_From_Inlined_Body --
+   -
+
+   function Comes_From_Inlined_Body (S : Source_Ptr) return Boolean is
+  SIE : Source_File_Record renames
+Source_File.Table (Get_Source_File_Index (S));
+   begin
+  return SIE.Inlined_Body;
+   end Comes_From_Inlined_Body;
+
---
-- Get_Column_Number --
---
Index: sinput.ads
===
--- sinput.ads  (revision 213201)
+++ sinput.ads  (working copy)
@@ -6,7 +6,7 @@
 --  --
 -- S p e c  --
 --  --
---  Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 1992-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -638,6 +638,13 @@
--  value of the instantiation if this location is within an instance.
--  If S is not within an instance, then this returns No_Location.
 
+   function Comes_From_Inlined_Body (S : Source_Ptr) return Boolean;
+   pragma Inline (Comes_From_Inlined_Body);
+   --  Given a source pointer S, returns whether it comes from an inlined body.
+   --  This allows distinguishing these source pointers from those that come
+   --  from instantiation of generics, since Instantiation_Location returns a
+   --  valid location in both cases.
+
function Top_Level_Location (S : Source_Ptr) return Source_Ptr;
--  Given a source pointer S, returns the argument unchanged if it is
--  not in an instantiation. If S is in an instantiation, then it returns


[Ada] Front-end inlining in GNATprove mode

2014-07-30 Thread Arnaud Charlet
In GNATprove mode, all subprograms are candidates for front-end inlining, to
simplify proofs.  This patch extends this transformation to subprogam bodies
that do not have a previous subprogram declaration. In this case the compiler
builds a declaration, transfers aspects, if any, from body to declaration, and
attempts to create a body_to_inline, as if the Inline_Always pragma was present
on every such body.

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

2014-07-30  Ed Schonberg  schonb...@adacore.com

* sem_ch6.adb (Hanalyze_Subprogram_Body_Helper): In GNATprove
mode, subprogram bodies without a previous declaration are also
candidates for front-end inlining.

Index: sem_ch6.adb
===
--- sem_ch6.adb (revision 213240)
+++ sem_ch6.adb (working copy)
@@ -2952,6 +2952,42 @@
Spec_Id := Disambiguate_Spec;
 else
Spec_Id := Find_Corresponding_Spec (N);
+
+   --  In GNATprove mode, if the body has no previous spec, create
+   --  one so that the inlining machinery can operate properly.
+   --  Transfer aspects, if any, to the new spec, so that they
+   --  are legal and can be processed ahead of the body.
+   --  We make two copies of the given spec, one for the new
+   --  declaration, and one for the body.
+
+   --  This cannot be done for a compilation unit, which is not
+   --  in a context where we can insert a new spec.
+
+   if No (Spec_Id)
+ and then GNATprove_Mode
+ and then Debug_Flag_QQ
+ and then Full_Analysis
+ and then Comes_From_Source (Body_Id)
+ and then Is_List_Member (N)
+   then
+  declare
+ Body_Spec : constant Node_Id :=
+   Copy_Separate_Tree (Specification (N));
+ New_Decl : constant Node_Id :=
+   Make_Subprogram_Declaration
+(Loc, Copy_Separate_Tree (Specification (N)));
+
+  begin
+ Insert_Before (N, New_Decl);
+ Move_Aspects (From = N, To = New_Decl);
+ Analyze (New_Decl);
+ Spec_Id := Defining_Entity (New_Decl);
+
+ Set_Specification (N, Body_Spec);
+ Body_Id := Analyze_Subprogram_Specification (Body_Spec);
+ Set_Corresponding_Spec (N, Spec_Id);
+  end;
+   end if;
 end if;
 
 --  If this is a duplicate body, no point in analyzing it


[Ada] SPARK 2014 aspects should not be delayed

2014-07-30 Thread Arnaud Charlet
This patch changes the categorization of SPARK 2014 aspects from delayed to
non-delayed. These aspects are equivalent to source pragmas which appear after
their related constructs. To deal with forward references, the generatd pragmas
are stored in N_Contract nodes and later analyzed at the end of the declarative
region containing the related construct. No test needed, no change in behavior.

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

2014-07-30  Hristian Kirtchev  kirtc...@adacore.com

* aspects.ads Add a comment explaining why SPARK 2014 aspects are
not delayed. Update the delay status of most SPARK 2014 aspects.
* sem_ch13.adb (Analyze_Aspect_Specifications): Update all calls
to Decorate_Aspect_And_Pragma and Insert_Delayed_Pragma to refert
to Decorate and Insert_Pragma. Add various comments concerning
the delay status of several SPARK 2014 aspects. The insertion
of Refined_State now uses routine Insert_After_SPARK_Mode.
(Decorate): New routine.
(Decorate_Aspect_And_Pragma): Removed.
(Insert_Delayed_Pragma): Removed.
(Insert_Pragma): New routine.

Index: aspects.ads
===
--- aspects.ads (revision 213242)
+++ aspects.ads (revision 213243)
@@ -543,6 +543,14 @@
--  information from the parent type, which must be frozen at that point
--  (since freezing the derived type first freezes the parent type).
 
+   --  SPARK 2014 aspects do not follow the general delay mechanism as they
+   --  act as annotations and cannot modify the attributes of their related
+   --  constructs. To handle forward references in such aspects, the compiler
+   --  delays the analysis of their respective pragmas by collecting them in
+   --  N_Contract nodes. The pragmas are then analyzed at the end of the
+   --  declarative region which contains the related construct. For details,
+   --  see routines Analyze_xxx_In_Decl_Part.
+
--  The following shows which aspects are delayed. There are three cases:
 
type Delay_Type is
@@ -593,12 +601,10 @@
   Aspect_Asynchronous = Always_Delay,
   Aspect_Attach_Handler   = Always_Delay,
   Aspect_Constant_Indexing= Always_Delay,
-  Aspect_Contract_Cases   = Always_Delay,
   Aspect_CPU  = Always_Delay,
   Aspect_Default_Iterator = Always_Delay,
   Aspect_Default_Value= Always_Delay,
   Aspect_Default_Component_Value  = Always_Delay,
-  Aspect_Depends  = Always_Delay,
   Aspect_Discard_Names= Always_Delay,
   Aspect_Dispatching_Domain   = Always_Delay,
   Aspect_Dynamic_Predicate= Always_Delay,
@@ -607,15 +613,12 @@
   Aspect_External_Tag = Always_Delay,
   Aspect_Export   = Always_Delay,
   Aspect_Favor_Top_Level  = Always_Delay,
-  Aspect_Global   = Always_Delay,
   Aspect_Implicit_Dereference = Always_Delay,
   Aspect_Import   = Always_Delay,
   Aspect_Independent  = Always_Delay,
   Aspect_Independent_Components   = Always_Delay,
   Aspect_Inline   = Always_Delay,
   Aspect_Inline_Always= Always_Delay,
-  Aspect_Initial_Condition= Always_Delay,
-  Aspect_Initializes  = Always_Delay,
   Aspect_Input= Always_Delay,
   Aspect_Interrupt_Handler= Always_Delay,
   Aspect_Interrupt_Priority   = Always_Delay,
@@ -639,9 +642,6 @@
   Aspect_Pure = Always_Delay,
   Aspect_Pure_Function= Always_Delay,
   Aspect_Read = Always_Delay,
-  Aspect_Refined_Depends  = Always_Delay,
-  Aspect_Refined_Global   = Always_Delay,
-  Aspect_Refined_State= Always_Delay,
   Aspect_Relative_Deadline= Always_Delay,
   Aspect_Remote_Access_Type   = Always_Delay,
   Aspect_Remote_Call_Interface= Always_Delay,
@@ -671,13 +671,21 @@
   Aspect_Annotate = Never_Delay,
   Aspect_Async_Readers= Never_Delay,
   Aspect_Async_Writers= Never_Delay,
+  Aspect_Contract_Cases   = Never_Delay,
   Aspect_Convention   = Never_Delay,
+  Aspect_Depends  = Never_Delay,
   Aspect_Dimension= Never_Delay,
   Aspect_Dimension_System = Never_Delay,
   Aspect_Effective_Reads  = Never_Delay,
   Aspect_Effective_Writes = Never_Delay,
+  Aspect_Global   = Never_Delay,
+  Aspect_Initial_Condition= 

[Ada] Implement compilation date and time output and functions

2014-07-30 Thread Arnaud Charlet
This patch causes the compiler to print the compilation time in
-gnatv or -gnatl mode (suppressible with debug flag -gnatd7).

It also provides new functions in GNAT.Source_Info to obtain
the compilation date and time (in a form compatible with the
use of the C macros __DATE__ and __TIME__.

Finally a new function System.OS_Lib.Current_Time_String is
introduced (and used by the compiler to implement the above).

The following test is compiled with -gnatl:

Compiling: ctime.adb
Source file time stamp: 2014-04-04 14:00:32
Compiled at: 2014-04-04 10:03:24

 1. with Text_IO; use Text_IO;
 2. with GNAT.Source_Info; use GNAT.Source_Info;
 3. procedure Ctime is
 4. begin
 5.Put_Line (Compilation_Date);
 6.Put_Line (Compilation_Time);
 7. end;

When run, the output is:

Jul 30 2014
10:03:24

Note: by its very nature, the above test is not suitable as a standard
regression test since of course its output changes each time it is run.

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

2014-07-30  Robert Dewar  de...@adacore.com

* debug.adb: Document that d7 suppresses compilation time output.
* errout.adb (Write_Header): Include compilation time in
header output.
* exp_intr.adb (Expand_Intrinsic_Call): Add
Compilation_Date/Compilation_Time (Expand_Source_Info): Expand
Compilation_Date/Compilation_Time.
* g-souinf.ads (Compilation_Date): New function
(Compilation_Time): New function.
* gnat1drv.adb (Gnat1drv): Set Opt.Compilation_Time.
* gnat_rm.texi (Compilation_Date): New function
(Compilation_Time): New function.
* opt.ads (Compilation_Time): New variable.
* s-os_lib.ads, s-os_lib.adb (Current_Time_String): New function.
* sem_intr.adb (Compilation_Date): New function.
(Compilation_Time): New function.
* snames.ads-tmpl (Name_Compilation_Date): New entry.
(Name_Compilation_Time): New entry.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 213242)
+++ gnat_rm.texi(working copy)
@@ -14637,6 +14637,8 @@
 
 @menu
 * Intrinsic Operators::
+* Compilation_Date::
+* Compilation_Time::
 * Enclosing_Entity::
 * Exception_Information::
 * Exception_Message::
@@ -14694,12 +14696,34 @@
 It is also possible to specify such operators for private types, if the
 full views are appropriate arithmetic types.
 
+@node Compilation_Date
+@section Compilation_Date
+@cindex Compilation_Date
+@noindent
+This intrinsic subprogram is used in the implementation of the
+library package @code{GNAT.Source_Info}.  The only useful use of the
+intrinsic import in this case is the one in this unit, so an
+application program should simply call the function
+@code{GNAT.Source_Info.Compilation_Date} to obtain the date of
+the current compilation (in local time format MMM DD ).
+
+@node Compilation_Time
+@section Compilation_Time
+@cindex Compilation_Time
+@noindent
+This intrinsic subprogram is used in the implementation of the
+library package @code{GNAT.Source_Info}.  The only useful use of the
+intrinsic import in this case is the one in this unit, so an
+application program should simply call the function
+@code{GNAT.Source_Info.Compilation_Time} to obtain the time of
+the current compilation (in local time format HH:MM:SS).
+
 @node Enclosing_Entity
 @section Enclosing_Entity
 @cindex Enclosing_Entity
 @noindent
 This intrinsic subprogram is used in the implementation of the
-library routine @code{GNAT.Source_Info}.  The only useful use of the
+library package @code{GNAT.Source_Info}.  The only useful use of the
 intrinsic import in this case is the one in this unit, so an
 application program should simply call the function
 @code{GNAT.Source_Info.Enclosing_Entity} to obtain the name of
@@ -14710,7 +14734,7 @@
 @cindex Exception_Information'
 @noindent
 This intrinsic subprogram is used in the implementation of the
-library routine @code{GNAT.Current_Exception}.  The only useful
+library package @code{GNAT.Current_Exception}.  The only useful
 use of the intrinsic import in this case is the one in this unit,
 so an application program should simply call the function
 @code{GNAT.Current_Exception.Exception_Information} to obtain
@@ -14721,7 +14745,7 @@
 @cindex Exception_Message
 @noindent
 This intrinsic subprogram is used in the implementation of the
-library routine @code{GNAT.Current_Exception}.  The only useful
+library package @code{GNAT.Current_Exception}.  The only useful
 use of the intrinsic import in this case is the one in this unit,
 so an application program should simply call the function
 @code{GNAT.Current_Exception.Exception_Message} to obtain
@@ -14732,7 +14756,7 @@
 @cindex Exception_Name
 @noindent
 This intrinsic subprogram is used in the implementation of the
-library routine @code{GNAT.Current_Exception}.  The only useful
+library package 

[Ada] Forbid the use of in attribute 'Update

2014-07-30 Thread Arnaud Charlet
This patch implements the following SPARK 2014 rule:

   4.4.1 (1) - The box symbol, , may not appear in any expression appearing
   in an update expression.

The patch also cleans up the analysis of attribute 'Update.


-- Source --


--  box_update.ads

package Box_Update with SPARK_Mode = On is
   type I  is range 1 .. 5;
   type T1 is range 1 .. 10
 with Default_Value = 5;

   type A1 is array (I) of T1;

   procedure Init1 (X : out A1);
end Box_Update;

--  box_update.adb

package body Box_Update with SPARK_Mode = On is
   procedure Init1 (X : out A1) is
  T : constant A1 := A1'(1 = 6, others = );
   begin
  X := T'Update(1 = );
   end Init1;
end Box_Update;


-- Compilation and output --


$ gcc -c box_update.adb
box_update.adb:5:23: default initialization not allowed in attribute Update

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

2014-07-30  Hristian Kirtchev  kirtc...@adacore.com

* sem_attr.adb (Analyze_Array_Component_Update): New routine.
(Analyze_Attribute): Major cleanup of attribute
'Update. The logic is now split into two distinct routines
depending on the type of the prefix. The use of  is now illegal
in attribute 'Update.
(Analyze_Record_Component_Update): New routine.
(Check_Component_Reference): Removed.
(Resolve_Attribute): Remove the return statement and ??? comment
following the processing for attribute 'Update. As a result,
the attribute now freezes its prefix.

Index: sem_attr.adb
===
--- sem_attr.adb(revision 213212)
+++ sem_attr.adb(working copy)
@@ -6220,69 +6220,158 @@
   
 
   when Attribute_Update = Update : declare
+ Common_Typ : Entity_Id;
+ --  The common type of a multiple component update for a record
+
  Comps : Elist_Id := No_Elist;
- Expr  : Node_Id;
+ --  A list used in the resolution of a record update. It contains the
+ --  entities of all record components processed so far.
 
- procedure Check_Component_Reference
-   (Comp : Entity_Id;
-Typ  : Entity_Id);
- --  Comp is a record component (possibly a discriminant) and Typ is a
- --  record type. Determine whether Comp is a legal component of Typ.
- --  Emit an error if Comp mentions a discriminant or is not a unique
- --  component reference in the update aggregate.
+ procedure Analyze_Array_Component_Update (Assoc : Node_Id);
+ --  Analyze and resolve array_component_association Assoc against the
+ --  index of array type P_Type.
 
- ---
- -- Check_Component_Reference --
- ---
+ procedure Analyze_Record_Component_Update (Comp : Node_Id);
+ --  Analyze and resolve record_component_association Comp against
+ --  record type P_Type.
 
- procedure Check_Component_Reference
-   (Comp : Entity_Id;
-Typ  : Entity_Id)
- is
-Comp_Name : constant Name_Id := Chars (Comp);
+ 
+ -- Analyze_Array_Component_Update --
+ 
 
-function Is_Duplicate_Component return Boolean;
---  Determine whether component Comp already appears in list Comps
+ procedure Analyze_Array_Component_Update (Assoc : Node_Id) is
+Expr  : Node_Id;
+High  : Node_Id;
+Index : Node_Id;
+Index_Typ : Entity_Id;
+Low   : Node_Id;
 
-
--- Is_Duplicate_Component --
-
+ begin
+--  The current association contains a sequence of indexes denoting
+--  an element of a multidimensional array:
 
-function Is_Duplicate_Component return Boolean is
-   Comp_Elmt : Elmt_Id;
+--(Index_1, ..., Index_N)
 
-begin
-   if Present (Comps) then
-  Comp_Elmt := First_Elmt (Comps);
-  while Present (Comp_Elmt) loop
- if Chars (Node (Comp_Elmt)) = Comp_Name then
-return True;
+--  Examine each individual index and resolve it against the proper
+--  index type of the array.
+
+if Nkind (First (Choices (Assoc))) = N_Aggregate then
+   Expr := First (Choices (Assoc));
+   while Present (Expr) loop
+
+  --  The use of others is illegal (SPARK RM 4.4.1(12))
+
+  if Nkind (Expr) = N_Others_Choice then
+ Error_Attr
+   (others choice not allowed in 

[Ada] Missing interface conversion in access type

2014-11-20 Thread Arnaud Charlet
The compiler silently skips the generation of code to perform the
conversion of an access type whose designated type is a class-wide
interface type, thus causing unexpected problems at runtime in
dispatching calls to the target object. After this patch the
following test compiles and executes without errors:

package Lists is
   type List is interface;

   function Element (Self : access List) return Natural is abstract;
end Lists;

limited with Lists;
package Types is
   type List_Access is access all Lists.List'Class;
end Types;

with Types;
with Lists;
with Ada.Finalization;

package My_Lists is
   type My_List is new Ada.Finalization.Controlled
 and Lists.List
   with null record;

   type My_List_Access is access all My_List'Class;

   overriding function Element (Self : access My_List) return Natural
 is (2);
end My_Lists;

with My_Lists;
with Types;
procedure Test is
   X : My_Lists.My_List_Access := new My_Lists.My_List;
   Y : Types.List_Access := Types.List_Access (X);  -- Test
begin
   if Y.Element /= 2 then
  raise Program_Error;
   end if;
end Test;

Command: gnatmake main.adb; ./main
No output

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

2014-11-20  Javier Miranda  mira...@adacore.com

* exp_ch4.adb (Expand_N_Type_Conversion): Add missing implicit
conversion to force the displacement of the pointer to the object
to reference the secondary dispatch table.

Index: exp_ch4.adb
===
--- exp_ch4.adb (revision 217828)
+++ exp_ch4.adb (working copy)
@@ -10622,7 +10622,9 @@
 
 --  Ada 2005 (AI-251): Handle interface type conversion
 
-if Is_Interface (Actual_Op_Typ) then
+if Is_Interface (Actual_Op_Typ)
+  or else Is_Interface (Actual_Targ_Typ)
+then
Expand_Interface_Conversion (N);
goto Done;
 end if;


[Ada] Lift limitation of inter-unit inlining with generic packages

2014-11-20 Thread Arnaud Charlet
This change lifts the arbitrary limitation on the number of iterations that
can be executed between loading of the inlined bodies and instantiation of
the generic bodies of external units when inter-unit inlining is activated.
It was previously limited to 1 but this may be not sufficient in some cases,
which can result in pragma Inline_Always not being honored.

The following code must compile quietly with -O -gnatn:

with Q; use Q;

package P is

   function F (Cal : Calendar) return Boolean;

end P;
package body P is

   function F (Cal : Calendar) return Boolean is
   begin
  return Pred (Cal);
   end;

end P;

with R; use R;

package Q is

   type Calendar is new Object_Ref;

   type Root_Calendar is new Root_Object with record
  B : Boolean;
   end record;

   type Root_Calendar_Ptr is access all Root_Calendar'Class;

   function Pred (Cal : Calendar) return Boolean;
   pragma Inline (Pred);

end Q;
package body Q is

   function Get_Calendar is new Get_Object (Root_Calendar, Root_Calendar_Ptr);
   pragma Inline (Get_Calendar);

   function Pred (Cal : Calendar) return Boolean is
  Cal_Object : constant Root_Calendar_Ptr
 := Get_Calendar (Object_Ref (Cal));
   begin
  return Cal_Object.B;
   end;
end Q;

with Ada.Finalization;

package R is

   type Root_Object is new Ada.Finalization.Controlled with record
  Reference_Count : Natural;
   end record;

   type Object_Ref is private;

   type Root_Object_Ptr is access all Root_Object'Class;

   generic
  type Object () is abstract new Root_Object with private;
  type Object_Ptr is access all Object'Class;
   function Get_Object (Ref : in Object_Ref) return Object_Ptr;

private

   type Object_Ref is new Ada.Finalization.Controlled with record
  Ptr : Root_Object_Ptr;
   end record;

end R;
package body R is

   function Get_Object (Ref : in Object_Ref) return Object_Ptr is
   begin
  return Object_Ptr (Ref.Ptr);
   end Get_Object;

end R;

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

2014-11-20  Eric Botcazou  ebotca...@adacore.com

* inline.adb (Analyze_Inlined_Bodies): Iterate between loading
of the inlined bodies and instantiation of the generic bodies
until no more bodies need to be loaded.

Index: inline.adb
===
--- inline.adb  (revision 217828)
+++ inline.adb  (working copy)
@@ -774,16 +774,21 @@
 end if;
 
 J := J + 1;
- end loop;
 
- --  The analysis of required bodies may have produced additional
- --  generic instantiations. To obtain further inlining, we perform
- --  another round of generic body instantiations. Establishing a
- --  fully recursive loop between inlining and generic instantiations
- --  is unlikely to yield more than this one additional pass.
+if J  Inlined_Bodies.Last then
 
- Instantiate_Bodies;
+   --  The analysis of required bodies may have produced additional
+   --  generic instantiations. To obtain further inlining, we need
+   --  to perform another round of generic body instantiations.
 
+   Instantiate_Bodies;
+
+   --  Symmetrically, the instantiation of required generic bodies
+   --  may have caused additional bodies to be inlined. To obtain
+   --  further inlining, we keep looping over the inlined bodies.
+end if;
+ end loop;
+
  --  The list of inlined subprograms is an overestimate, because it
  --  includes inlined functions called from functions that are compiled
  --  as part of an inlined package, but are not themselves called. An


[Ada] Fix costly call to Following_Address_Clause

2014-11-20 Thread Arnaud Charlet
This change makes is so that Following_Address_Clause is invoked only if this
is really necessary from Analyze_Object_Declaration.  This saves about 1% of
the compilation time at low optimization levels.  No functional changes.

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

2014-11-20  Eric Botcazou  ebotca...@adacore.com

* sem_ch3.adb (Analyze_Object_Declaration): Swap a couple of
tests in a condition so Following_Address_Clause is invoked
only if need be.
* exp_util.ads (Following_Address_Clause): Add small note.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 217828)
+++ sem_ch3.adb (working copy)
@@ -3648,8 +3648,13 @@
 
  if Comes_From_Source (N)
and then Expander_Active
+   and then Nkind (E) = N_Aggregate
+
+   --  Note the importance of doing this the following test after the
+   --  N_Aggregate test to avoid inefficiencies from too many calls to
+   --  the function Following_Address_Clause which can be expensive.
+
and then Present (Following_Address_Clause (N))
-   and then Nkind (E) = N_Aggregate
  then
 Set_Etype (E, T);
 
Index: exp_util.ads
===
--- exp_util.ads(revision 217828)
+++ exp_util.ads(working copy)
@@ -507,6 +507,10 @@
--  current declarative part to look for an address clause for the object
--  being declared, and returns the clause if one is found, returns
--  Empty otherwise.
+   --
+   --  Note: this function can be costly and must be invoked with special care.
+   --  Possibly we could introduce a flag at parse time indicating the presence
+   --  of an address clause to speed this up???
 
procedure Force_Evaluation
  (Exp  : Node_Id;


[Ada] Handling of function calls to predefined operators in ASIS

2014-11-20 Thread Arnaud Charlet
An operator that is called in functional notation is rewritten as an operator
so that its operands can be properly resolved. ASIS needs the semantic info
to be available on the original node, so in ASIS mode the resolved operands
are linked back to the original call. This patch takes into account that the
call may have had named associations, using the standard operator arguments
Left and Right.

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

2014-11-20  Ed Schonberg  schonb...@adacore.com

* sem_res.adb (Make_Call_Into_Operator): In ASIS mode, propagate
back the resolved operands to the original call node, taking
into account that the original call may have named associations.

Index: sem_res.adb
===
--- sem_res.adb (revision 217828)
+++ sem_res.adb (working copy)
@@ -1793,16 +1793,62 @@
 and then Nkind (N) in N_Op
 and then Nkind (Original_Node (N)) = N_Function_Call
   then
- if Is_Binary then
-Rewrite (First (Parameter_Associations (Original_Node (N))),
-   Relocate_Node (Left_Opnd (N)));
-Rewrite (Next (First (Parameter_Associations (Original_Node (N,
-   Relocate_Node (Right_Opnd (N)));
- else
-Rewrite (First (Parameter_Associations (Original_Node (N))),
-   Relocate_Node (Right_Opnd (N)));
- end if;
+ declare
+L : constant Node_Id := Left_Opnd  (N);
+R : constant Node_Id := Right_Opnd (N);
 
+Old_First : constant Node_Id :=
+  First (Parameter_Associations (Original_Node (N)));
+Old_Sec   : Node_Id;
+
+ begin
+if Is_Binary then
+   Old_Sec   := Next (Old_First);
+
+   --  If the original call has named associations, replace the
+   --  explicit actual parameter in the association with the proper
+   --  resolved operand.
+
+   if Nkind (Old_First) = N_Parameter_Association then
+  if Chars (Selector_Name (Old_First)) =
+ Chars (First_Entity (Op_Id))
+  then
+ Rewrite (Explicit_Actual_Parameter (Old_First),
+   Relocate_Node (L));
+  else
+ Rewrite (Explicit_Actual_Parameter (Old_First),
+   Relocate_Node (R));
+  end if;
+
+   else
+  Rewrite (Old_First, Relocate_Node (L));
+   end if;
+
+   if Nkind (Old_Sec) = N_Parameter_Association then
+  if Chars (Selector_Name (Old_Sec))  =
+ Chars (First_Entity (Op_Id))
+  then
+ Rewrite (Explicit_Actual_Parameter (Old_Sec),
+   Relocate_Node (L));
+  else
+ Rewrite (Explicit_Actual_Parameter (Old_Sec),
+   Relocate_Node (R));
+  end if;
+
+   else
+  Rewrite (Old_Sec, Relocate_Node (R));
+   end if;
+
+else
+   if Nkind (Old_First) = N_Parameter_Association then
+  Rewrite (Explicit_Actual_Parameter (Old_First),
+Relocate_Node (R));
+   else
+  Rewrite (Old_First, Relocate_Node (R));
+   end if;
+end if;
+ end;
+
  Set_Parent (Original_Node (N), Parent (N));
   end if;
end Make_Call_Into_Operator;


[Ada] Improper assignment on indexing operation with implicit dereference

2014-11-20 Thread Arnaud Charlet
If the left-hand side of an assignment is an Ada 2012 generalized indexing
with an implicit derenference, the compiler must verify that the type of
the access discriminant that provides the implicit dereference is not an
access_to_constant.

Compiling ada_test.adb must yield:

   ada_test.adb:24:25: left hand side of assignment must be a variable
   ada_test.adb:25:04: left hand side of assignment must be a variable

---
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Ada_Test is

   type Obj is record
  A : aliased Integer;
   end record;

   type Obj_Access is access all Obj;

   type Accessor (Data : access constant Integer) is null record with
 Implicit_Dereference = Data;

   function Get_Int (This : Obj_Access) return Accessor is
   begin
  return Accessor'(Data = This.A'Access);
   end Get_Int;

   X : aliased Obj := (A = 11);
   X_Ptr : Obj_Access := X'Access;

begin
   Get_Int (X_Ptr).Data.all := 33;   -- Error
   Get_Int (X_Ptr) := 33;-- Error
   Put (X.A);-- Should never execute..
   New_Line;
end Ada_Test;

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

2014-11-20  Ed Schonberg  schonb...@adacore.com

* sem_util.adb (Is_Variable): For an Ada 2012 implicit
dereference introduced for an indexing opertion, check that the
type of the corresponding access discriminant is not an access
to constant.

Index: sem_util.adb
===
--- sem_util.adb(revision 217829)
+++ sem_util.adb(working copy)
@@ -12806,12 +12806,14 @@
  Is_Variable_Prefix (Original_Node (Prefix (N)));
 
   --  in Ada 2012, the dereference may have been added for a type with
-  --  a declared implicit dereference aspect.
+  --  a declared implicit dereference aspect. Check that it is not an
+  --  access to constant.
 
   elsif Nkind (N) = N_Explicit_Dereference
 and then Present (Etype (Orig_Node))
 and then Ada_Version = Ada_2012
 and then Has_Implicit_Dereference (Etype (Orig_Node))
+and then not Is_Access_Constant (Etype (Prefix (N)))
   then
  return True;
 


[Ada] Rework win32_wait to behave more like the UNIX waitpid()

2014-11-20 Thread Arnaud Charlet
The following changes are importants:

- It is possible to have multiple tasks waiting for a child process
  to terminate.

- When a child terminates, a single wait call will receive the
  corresponding process id.

- A call to wait will handle new incoming child processes.

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

2014-11-20  Pascal Obry  o...@adacore.com

* initialize.c (ProcListCS): New extern variable (critical section).
(ProcListEvt): New extern variable (handle).
(__gnat_initialize)[Win32]: Initialize the ProcListCS critical
section object and the ProcListEvt event.
* final.c (__gnat_finalize)[Win32]: Properly finalize the
ProcListCS critical section and the ProcListEvt event.
* adaint.c (ProcListEvt): New Win32 event handle.
(EnterCS): New routine to enter the critical section when dealing with
child processes chain list.
(LeaveCS): As above to exit from the critical section.
(SignalListChanged): Routine to signal that the chain process list has
been updated.
(add_handle): Use EnterCS/LeaveCS, also call SignalListChanged when the
handle has been added.
(__gnat_win32_remove_handle): Use EnterCS/LeaveCS,
also call SignalListChanged if the handle has been found and removed.
(remove_handle): Routine removed, implementation merged with the above.
(win32_wait): Use EnterCS/LeaveCS for the critical section. Properly
copy the PID list locally to ensure that even if the list is updated
the local copy remains valid. Add into the hl (handle list) the
ProcListEvt handle. This handle is used to signal that a change has
been made into the process chain list. This is to ensure that a waiting
call can be resumed to take into account new processes. We also make
sure that if the handle was not found into the list we start over
the wait call. Indeed another concurrent call to win32_wait()
could already have handled this process.

Index: final.c
===
--- final.c (revision 217828)
+++ final.c (working copy)
@@ -6,7 +6,7 @@
  *  *
  *  C Implementation File   *
  *  *
- *  Copyright (C) 1992-2011, Free Software Foundation, Inc. *
+ *  Copyright (C) 1992-2014, Free Software Foundation, Inc. *
  *  *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -40,11 +40,29 @@
at all, the intention is that this be replaced by system specific code
where finalization is required.  */
 
+#if defined (__MINGW32__)
+#include mingw32.h
+#include windows.h
+
+extern CRITICAL_SECTION ProcListCS;
+extern HANDLE ProcListEvt;
+
 void
 __gnat_finalize (void)
 {
+  /* delete critical section and event handle used for the
+ processes chain list */
+  DeleteCriticalSection(ProcListCS);
+  CloseHandle (ProcListEvt);
 }
 
+#else
+void
+__gnat_finalize (void)
+{
+}
+#endif
+
 #ifdef __cplusplus
 }
 #endif
Index: initialize.c
===
--- initialize.c(revision 217828)
+++ initialize.c(working copy)
@@ -74,6 +74,8 @@
 
 extern int gnat_argc;
 extern char **gnat_argv;
+extern CRITICAL_SECTION ProcListCS;
+extern HANDLE ProcListEvt;
 
 #ifdef GNAT_UNICODE_SUPPORT
 
@@ -138,6 +140,11 @@
   given that we have set Max_Digits etc with this in mind */
__gnat_init_float ();
 
+   /* Initialize the critical section and event handle for the win32_wait()
+  implementation, see adaint.c */
+   InitializeCriticalSection (ProcListCS);
+   ProcListEvt = CreateEvent (NULL, FALSE, FALSE, NULL);
+
 #ifdef GNAT_UNICODE_SUPPORT
/* Set current code page for filenames handling. */
{
Index: adaint.c
===
--- adaint.c(revision 217836)
+++ adaint.c(working copy)
@@ -2311,21 +2311,30 @@
for locking and unlocking tasks since we do not support multiple
threads on this configuration (Cert run time on native Windows). */
 
-static void dummy (void)
+static void EnterCS (void) {}
+static void LeaveCS (void) {}
+static void SignalListChanged (void) {}
+
+#else
+
+CRITICAL_SECTION ProcListCS;
+HANDLE ProcListEvt;
+
+static void EnterCS (void)
 {
+  EnterCriticalSection(ProcListCS);
 }
 
-void (*Lock_Task) ()   = dummy;
-void (*Unlock_Task) () = dummy;
+static void LeaveCS (void)
+{
+  LeaveCriticalSection(ProcListCS);
+}
 
-#else
+static void SignalListChanged (void)
+{
+  SetEvent (ProcListEvt);
+}
 
-#define Lock_Task 

[Ada] Attributes 'Old and 'Update must preserve the tag of their prefix

2014-11-20 Thread Arnaud Charlet
The patch modifies the expansion of attributes 'Old and 'Update to ensure that
the tag of a tagged prefix is not modified as a result attribute evaluation.


-- Source --


--  types.ads

package Types is
   type Root is tagged record
  X : Integer;
   end record;

   procedure Show (R : Root);

   type Ext is new Root with record
  Y : Integer;
   end record;

   overriding procedure Show (R : Ext);
end Types;

--  types.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Types is
   procedure Show (R : Root) is
   begin
  Put_Line ((root) X =  R.X'Img);
   end Show;

   overriding procedure Show (R : Ext) is
   begin
  Put_Line ((ext) X =  R.X'Img);
  Put_Line ((ext) Y =  R.Y'Img);
   end Show;
end Types;

--  main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Types;   use Types;

procedure Main is
   procedure Show_Me (R : Root) is
  Tmp : Root'Class := R;
   begin
  Show (Tmp);
   end Show_Me;

   procedure Wibble (R : Root) is
   begin
  Show_Me (R);
  Show_Me (R'Update (X = 5));
   end Wibble;

   A : Ext;
begin
   A.X := 0;
   A.Y := 1;

   Wibble (Root (A));
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
(ext) X = 0
(ext) Y = 1
(ext) X = 5
(ext) Y = 1

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

2014-11-20  Hristian Kirtchev  kirtc...@adacore.com

* exp_attr.adb (Expand_N_Attribute_Reference,
Expand_Update_Attribute): Preserve the tag of a prefix by offering
a specific view of the class-wide version of the prefix.

Index: exp_attr.adb
===
--- exp_attr.adb(revision 217828)
+++ exp_attr.adb(working copy)
@@ -1021,6 +1021,9 @@
   Pref  : constant Node_Id   := Prefix (N);
   Typ   : constant Entity_Id := Etype (Pref);
   Blk   : Node_Id;
+  CW_Decl   : Node_Id;
+  CW_Temp   : Entity_Id;
+  CW_Typ: Entity_Id;
   Decls : List_Id;
   Installed : Boolean;
   Loc   : Source_Ptr;
@@ -1338,19 +1341,56 @@
   --  Step 3: Create a constant to capture the value of the prefix at the
   --  entry point into the loop.
 
-  --  Generate:
-  --Temp : constant type of Pref := Pref;
-
   Temp_Id := Make_Temporary (Loc, 'P');
 
-  Temp_Decl :=
-Make_Object_Declaration (Loc,
-  Defining_Identifier = Temp_Id,
-  Constant_Present= True,
-  Object_Definition   = New_Occurrence_Of (Typ, Loc),
-  Expression  = Relocate_Node (Pref));
-  Append_To (Decls, Temp_Decl);
+  --  Preserve the tag of the prefix by offering a specific view of the
+  --  class-wide version of the prefix.
 
+  if Is_Tagged_Type (Typ) then
+
+ --  Generate:
+ --CW_Temp : constant Typ'Class := Typ'Class (Pref);
+
+ CW_Temp := Make_Temporary (Loc, 'T');
+ CW_Typ  := Class_Wide_Type (Typ);
+
+ CW_Decl :=
+   Make_Object_Declaration (Loc,
+ Defining_Identifier = CW_Temp,
+ Constant_Present= True,
+ Object_Definition   = New_Occurrence_Of (CW_Typ, Loc),
+ Expression  =
+   Convert_To (CW_Typ, Relocate_Node (Pref)));
+ Append_To (Decls, CW_Decl);
+
+ --  Generate:
+ --Temp : Typ renames Typ (CW_Temp);
+
+ Temp_Decl :=
+   Make_Object_Renaming_Declaration (Loc,
+ Defining_Identifier = Temp_Id,
+ Subtype_Mark= New_Occurrence_Of (Typ, Loc),
+ Name=
+   Convert_To (Typ, New_Occurrence_Of (CW_Temp, Loc)));
+ Append_To (Decls, Temp_Decl);
+
+  --  Non-tagged case
+
+  else
+ CW_Decl := Empty;
+
+ --  Generate:
+ --Temp : constant Typ := Pref;
+
+ Temp_Decl :=
+   Make_Object_Declaration (Loc,
+ Defining_Identifier = Temp_Id,
+ Constant_Present= True,
+ Object_Definition   = New_Occurrence_Of (Typ, Loc),
+ Expression  = Relocate_Node (Pref));
+ Append_To (Decls, Temp_Decl);
+  end if;
+
   --  Step 4: Analyze all bits
 
   Installed := Current_Scope = Scope (Loop_Id);
@@ -1374,6 +1414,10 @@
   --  the declaration of the constant.
 
   else
+ if Present (CW_Decl) then
+Analyze (CW_Decl);
+ end if;
+
  Analyze (Temp_Decl);
   end if;
 
@@ -4358,19 +4402,13 @@
   -
 
   when Attribute_Old = Old : declare
- Asn_Stm : Node_Id;
+ Typ : constant Entity_Id := Etype (N);
+ CW_Temp : Entity_Id;
+ CW_Typ  : Entity_Id;
  Subp: Node_Id;
  Temp: Entity_Id;
 
   begin
- Temp := Make_Temporary (Loc, 'T', Pref);
-
- --  Set the entity kind now in order to mark 

[Ada] Interaction between 'Loop_Entry, 'Old, 'Update and Extensions_Visible

2014-11-20 Thread Arnaud Charlet
This patch the following SPARK rule (the part about 'Loop_Entry, 'Old, 'Update)

   If the Extensions_Visible aspect is False for a subprogram, then certain
   restrictions are imposed on the use of any parameter of the subprogram which
   is of a specific tagged type. Such a parameter shall not be converted to a
   class-wide type. Such a parameter shall not be passed as an actual parameter
   in a call to a subprogram whose Extensions_Visible aspect is True. These
   restrictions also apply to any parenthesized expression, qualified
   expression, or type conversion whose operand is subject to these
   restrictions, to any Old, Update, or Loop_Entry attribute_reference whose
   prefix is subject to these restrictions, and to any conditional expression
   having at least one dependent_expression which is subjec to these
   restrictions.


-- Source --


--  test_loop_entry_old_update.adb

procedure Test_Loop_Entry_Old_Update is

   -- Test that Extensions_Visible restrictions are enforced for
   -- Old, Update, and Loop_Entry attribute references.

   pragma Assertion_Policy (Check);

   package Pkg is
  type T is abstract tagged record Int1, Int2, Int3 : Integer; end record;
  function Is_Bodacious (X : T) return Boolean is abstract;
   end Pkg;
   use Pkg;

   procedure P1 (X : in out T) with
 Post = Is_Bodacious (T'Class (X'Old)), --  ERROR
 Extensions_Visible = False;
   procedure P1 (X : in out T) is begin null; end P1;

   procedure P2 (X : in out T) with Extensions_Visible = False;
   procedure P2 (X : in out T) is
   begin
  if Is_Bodacious (T'Class (X'Update (Int1 = 123))) then--  ERROR
 X.Int1 := 123;
  end if;
   end P2;

   procedure P3 (X : in out T) with Extensions_Visible = False;
   procedure P3 (X : in out T) is
   begin
  for I in 1 .. 10 loop
 X.Int1 := X.Int1 + 1;
 pragma Assert ((X.Int1 /= X.Int2)
   or else Is_Bodacious (T'Class (X'Loop_Entry)));   --  ERROR
  end loop;
   end P3;

   procedure P4 (X : in out T; Y : T'Class) with Extensions_Visible = False;
   procedure P4 (X : in out T; Y : T'Class) is
   begin
  if Is_Bodacious
(T'Class
  (T'(if X.Int1 = X.Int2 --  ERROR
  then X'Update (Int1 = X.Int1 + 1)
  else T (Y then
  X.Int1 := 456;
  end if;
   end P4;

begin null; end Test_Loop_Entry_Old_Update;


-- Compilation and output --


$ gcc -c test_loop_entry_old_update.adb
test_loop_entry_old_update.adb:15:38: formal parameter with Extensions_Visible
  False cannot be converted to class-wide type
test_loop_entry_old_update.adb:22:34: formal parameter with Extensions_Visible
  False cannot be converted to class-wide type
test_loop_entry_old_update.adb:33:44: formal parameter with Extensions_Visible
  False cannot be converted to class-wide type
test_loop_entry_old_update.adb:42:13: formal parameter with Extensions_Visible
  False cannot be converted to class-wide type

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

2014-11-20  Hristian Kirtchev  kirtc...@adacore.com

* sem_util.adb (Is_EVF_Expression): Include
attributes 'Loop_Entry, 'Old and 'Update to the logic.

Index: sem_util.adb
===
--- sem_util.adb(revision 217835)
+++ sem_util.adb(working copy)
@@ -10846,6 +10846,16 @@
  N_Type_Conversion)
   then
  return Is_EVF_Expression (Expression (N));
+
+  --  Attributes 'Loop_Entry, 'Old and 'Update are an EVF expression when
+  --  their prefix denotes an EVF expression.
+
+  elsif Nkind (N) = N_Attribute_Reference
+and then Nam_In (Attribute_Name (N), Name_Loop_Entry,
+ Name_Old,
+ Name_Update)
+  then
+ return Is_EVF_Expression (Prefix (N));
   end if;
 
   return False;


[Ada] Add missing SPARK_Mode aspects/pragmas on formal containers

2014-11-20 Thread Arnaud Charlet
While the library of formal maps/sets correctly set SPARK_Mode on spec
(On) and private part / body (Off), it was not the case for lists and
vectors, thus causing some errors in GNATprove when instantiating such
formal containers because bodies contain non-SPARK features (e.g. access
types in formal vectors). Now fixed, which requires for formal lists and
vectors that they are instantiated at library level, as other formal
containers.

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

2014-11-20  Yannick Moy  m...@adacore.com

* a-cfdlli.adb, a-cfdlli.ads, a-cfinve.adb, a-cfinve.ads,
* a-cofove.adb, a-cofove.ads: Mark spec as SPARK_Mode, and private
part/body as SPARK_Mode Off.
* a-cfhama.adb, a-cfhama.ads, a-cfhase.adb, a-cfhase.ads,
* a-cforma.adb, a-cforma.ads, a-cforse.adb, a-cforse.ads: Use
aspect instead of pragma for uniformity.

Index: a-cfdlli.adb
===
--- a-cfdlli.adb(revision 217828)
+++ a-cfdlli.adb(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- B o d y  --
 --  --
---  Copyright (C) 2010-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 2010-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -27,7 +27,9 @@
 
 with System;  use type System.Address;
 
-package body Ada.Containers.Formal_Doubly_Linked_Lists is
+package body Ada.Containers.Formal_Doubly_Linked_Lists with
+  SPARK_Mode = Off
+is
 
---
-- Local Subprograms --
Index: a-cfdlli.ads
===
--- a-cfdlli.ads(revision 217828)
+++ a-cfdlli.ads(working copy)
@@ -61,9 +61,11 @@
with function = (Left, Right : Element_Type)
   return Boolean is ;
 
-package Ada.Containers.Formal_Doubly_Linked_Lists is
+package Ada.Containers.Formal_Doubly_Linked_Lists with
+  Pure,
+  SPARK_Mode
+is
pragma Annotate (GNATprove, External_Axiomatization);
-   pragma Pure;
 
type List (Capacity : Count_Type) is private with
  Iterable = (First   = First,
@@ -337,6 +339,7 @@
--  scanned yet.
 
 private
+   pragma SPARK_Mode (Off);
 
type Node_Type is record
   Prev: Count_Type'Base := -1;
Index: a-cfhase.adb
===
--- a-cfhase.adb(revision 217828)
+++ a-cfhase.adb(working copy)
@@ -35,8 +35,9 @@
 
 with System; use type System.Address;
 
-package body Ada.Containers.Formal_Hashed_Sets is
-   pragma SPARK_Mode (Off);
+package body Ada.Containers.Formal_Hashed_Sets with
+  SPARK_Mode = Off
+is
 
---
-- Local Subprograms --
Index: a-cfhase.ads
===
--- a-cfhase.ads(revision 217828)
+++ a-cfhase.ads(working copy)
@@ -67,10 +67,11 @@
 
with function = (Left, Right : Element_Type) return Boolean is ;
 
-package Ada.Containers.Formal_Hashed_Sets is
+package Ada.Containers.Formal_Hashed_Sets with
+  Pure,
+  SPARK_Mode
+is
pragma Annotate (GNATprove, External_Axiomatization);
-   pragma Pure;
-   pragma SPARK_Mode (On);
 
type Set (Capacity : Count_Type; Modulus : Hash_Type) is private with
  Iterable = (First   = First,
@@ -335,9 +336,10 @@
--  scanned yet.
 
 private
-   pragma Inline (Next);
pragma SPARK_Mode (Off);
 
+   pragma Inline (Next);
+
type Node_Type is
   record
  Element : Element_Type;
Index: a-cfinve.adb
===
--- a-cfinve.adb(revision 217828)
+++ a-cfinve.adb(working copy)
@@ -26,7 +26,9 @@
 -- http://www.gnu.org/licenses/.  --
 --
 
-package body Ada.Containers.Formal_Indefinite_Vectors is
+package body Ada.Containers.Formal_Indefinite_Vectors with
+  SPARK_Mode = Off
+is
 
function H (New_Item : Element_Type) return Holder renames To_Holder;
function E (Container : Holder) return Element_Type renames Get;
Index: a-cfinve.ads
===
--- a-cfinve.ads(revision 217828)
+++ a-cfinve.ads(working copy)
@@ -52,7 +52,9 @@
--  size, and heap allocation will be avoided. If False, the containers can
--  grow via heap allocation.
 
-package Ada.Containers.Formal_Indefinite_Vectors is
+package 

[Ada] Generate VC in GNATprove instead of error for empty range check

2014-11-20 Thread Arnaud Charlet
Range checks on empty ranges typically correspond to deactivated code
based on a given configuration (say, dead code inside a loop over the
empty range). In GNATprove mode, instead of issuing an error message
(which would stop analysis), enable the range check so that GNATprove
will issue a message if it cannot prove that the check is unreachable.

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

2014-11-20  Yannick Moy  m...@adacore.com

* checks.adb (Apply_Scalar_Range_Check): In GNATprove mode,
put a range check when an empty range is used, instead of an
error message.
* sinfo.ads Update comment on GNATprove mode.

Index: sinfo.ads
===
--- sinfo.ads   (revision 217828)
+++ sinfo.ads   (working copy)
@@ -581,6 +581,12 @@
--   bounds are generated from an expression: Expand_Subtype_From_Expr
--   should be noop.
 
+   --5. Errors (instead of warnings) are issued on compile-time known
+   --   constraint errors, except in a few selected cases where it should
+   --   be allowed to let analysis proceed (e.g. range checks on empty
+   --   ranges, typically in deactivated code based on a given
+   --   configuration).
+
---
-- Check Flag Fields --
---
Index: checks.adb
===
--- checks.adb  (revision 217828)
+++ checks.adb  (working copy)
@@ -2926,7 +2926,21 @@
   --  since all possible values will raise CE).
 
   if Lov  Hiv then
- Bad_Value;
+
+ --  In GNATprove mode, do not issue a message in that case
+ --  (which would be an error stopping analysis), as this
+ --  likely corresponds to deactivated code based on a
+ --  given configuration (say, dead code inside a loop over
+ --  the empty range). Instead, we enable the range check
+ --  so that GNATprove will issue a message if it cannot be
+ --  proved.
+
+ if GNATprove_Mode then
+Enable_Range_Check (Expr);
+ else
+Bad_Value;
+ end if;
+
  return;
   end if;
 


[Ada] Give error message if duplicate Linker_Section given

2014-11-20 Thread Arnaud Charlet
Like other similar pragmas, we should disallow duplicate pragma or
aspect Linker_Section for non-overloadable entities (for the case
of overloading, the pragma only applies to previous entities which
do not have such a pragma).

The following should compile with the given error:

 1. package Pkg1 is
 2.Var_Dyn : natural;
 3.pragma Linker_Section (Var_Dyn, .data_dyn);
 4.pragma Linker_Section (Var_Dyn, .data_dyn1);
  |
 Linker_Section already specified for Var_Dyn at line 3

 5. end Pkg1;

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

2014-11-20  Robert Dewar  de...@adacore.com

* sem_prag.adb (Analyze_Pragma, case Linker_Section): Detect
duplicate Linker_Section.

Index: sem_prag.adb
===
--- sem_prag.adb(revision 217838)
+++ sem_prag.adb(working copy)
@@ -16380,6 +16380,7 @@
  when Pragma_Linker_Section = Linker_Section : declare
 Arg : Node_Id;
 Ent : Entity_Id;
+LPE : Node_Id;
 
  begin
 GNAT_Pragma;
@@ -16398,9 +16399,18 @@
 case Ekind (Ent) is
 
--  Objects (constants and variables) and types. For these cases
-   --  all we need to do is to set the Linker_Section_pragma field.
+   --  all we need to do is to set the Linker_Section_pragma field,
+   --  checking that we do not have a duplicate.
 
when E_Constant | E_Variable | Type_Kind =
+  LPE := Linker_Section_Pragma (Ent);
+
+  if Present (LPE) then
+ Error_Msg_Sloc := Sloc (LPE);
+ Error_Msg_NE
+   (Linker_Section already specified for #, Arg1, Ent);
+  end if;
+
   Set_Linker_Section_Pragma (Ent, N);
 
--  Subprograms


[Ada] gnat1: back end switch -G nnn (PR ada/47500)

2014-11-20 Thread Arnaud Charlet
On platform where the switch is allowed, the gcc driver, when called with
-Gnnn (nnn is a non negative number) invokes the compiler (gnat1) with
-G nnn. This patch skips the argument nnn after -G, so that it is not
taken as a source file name.

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

2014-11-20  Vincent Celier  cel...@adacore.com

PR ada/47500
* back_end.adb (Scan_Back_End_Switches): Skip switch -G and
its argument.

Index: back_end.adb
===
--- back_end.adb(revision 217828)
+++ back_end.adb(working copy)
@@ -232,9 +232,10 @@
  Last  : constant Natural  := Switch_Last (Switch_Chars);
 
   begin
- --  Skip -o or internal GCC switches together with their argument
+ --  Skip -o, -G or internal GCC switches together with their argument.
 
  if Switch_Chars (First .. Last) = o
+   or else Switch_Chars (First .. Last) = G
or else Is_Internal_GCC_Switch (Switch_Chars)
  then
 Next_Arg := Next_Arg + 1;


[Ada] Spurious errors on extension aggregate for limited type

2014-11-20 Thread Arnaud Charlet
This patch fixes two errors in the handling of extension aggregates for limited
types: Ancestor part of extension aggregate can itself be an extension aggregate
as well as a function call that is rewritten as a reference.

The following must compile quietly:

   gcc -c p2.adb
   gcc -c bugzilla.ads

---
package body P1 is
function Create return T1 is
begin
   return (Length = 3);
end Create;
end P1;
---
package P1 is
type T1 is tagged limited private;

function Create return T1;
private
type T1 (Length : Positive := 3) is
  tagged limited null record;
end P1;
---
with P1;
package P2 is
type T2 is
  limited new P1.T1 with null record;

function Create return T2;
end P2;
---
package body P2 is
function Create return T2 is
begin
   return (P1.Create with null record);
end Create;
end P2;
---
with Ada.Finalization;
package Bugzilla is
   type T1 is limited new Ada.Finalization.Limited_Controlled with null record;
   type T2 is new T1 with null record;
   X : T2 := (T1 with null record);
   Z : T2 := (T1'(Ada.Finalization.Limited_Controlled with null record)
   with null record);
end Bugzilla;

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

2014-11-20  Ed Schonberg  schonb...@adacore.com

* sem_aggr.adb (Valid_Limited_Ancestor): Ancestor part of
extension aggregate can itself be an extension aggregate, as
well as a call that is rewritten as a reference.

Index: sem_aggr.adb
===
--- sem_aggr.adb(revision 217828)
+++ sem_aggr.adb(working copy)
@@ -2663,12 +2663,19 @@
 
   function Valid_Limited_Ancestor (Anc : Node_Id) return Boolean is
   begin
- if Is_Entity_Name (Anc)
-   and then Is_Type (Entity (Anc))
+ if Is_Entity_Name (Anc) and then Is_Type (Entity (Anc)) then
+return True;
+
+ --  The ancestor must be a call or an aggregate, but a call may
+ --  have been expanded into a temporary, so check original node.
+
+ elsif Nkind_In (Anc, N_Aggregate,
+  N_Extension_Aggregate,
+  N_Function_Call)
  then
 return True;
 
- elsif Nkind_In (Anc, N_Aggregate, N_Function_Call) then
+ elsif Nkind (Original_Node (Anc)) = N_Function_Call then
 return True;
 
  elsif Nkind (Anc) = N_Attribute_Reference


[Ada] Inter-unit inlining of expression functions with -gnatn1

2014-11-20 Thread Arnaud Charlet
This enables inter-unit inlining of expression functions with -gnatn1, or more
simply with -O1/-O2 -gnatn.  These functions are automatically candidates for
inlining, but there were actually inlined across units only with -gnatn2, or
more simply -O3 -gnatn.

The following program must compile without warnings with -O -gnatn -Winline:

with Q; use Q;

procedure P (I : Integer) is
begin
  if Process (I) /= 2 * I then
raise Program_Error;
  end if;
end;
package Q is

  function Process (I : Integer) return Integer;
  pragma Inline (Process);

end Q;
with R; use R;

package body Q is

  function Process (I : Integer) return Integer is
  begin
return Process2 (I) + Process3 (I);
  end;

end Q;
package R is

  function Process2 (I : Integer) return Integer;

  function Process3 (I : Integer) return Integer is (I);

private

  function Process2 (I : Integer) return Integer is (I);

end R;

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

2014-11-20  Eric Botcazou  ebotca...@adacore.com

* inline.adb (Add_Inlined_Subprogram): Insert all programs
generated as a body or whose declaration was provided along with
the body.

Index: inline.adb
===
--- inline.adb  (revision 217842)
+++ inline.adb  (working copy)
@@ -454,6 +454,7 @@
 
procedure Add_Inlined_Subprogram (Index : Subp_Index) is
   E: constant Entity_Id := Inlined.Table (Index).Name;
+  Decl : constant Node_Id   := Parent (Declaration_Node (E));
   Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
 
   procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id);
@@ -486,14 +487,17 @@
begin
   --  If the subprogram is to be inlined, and if its unit is known to be
   --  inlined or is an instance whose body will be analyzed anyway or the
-  --  subprogram has been generated by the compiler, and if it is declared
+  --  subprogram was generated as a body by the compiler (for example an
+  --  initialization procedure) or its declaration was provided along with
+  --  the body (for example an expression function), and if it is declared
   --  at the library level not in the main unit, and if it can be inlined
   --  by the back-end, then insert it in the list of inlined subprograms.
 
   if Is_Inlined (E)
 and then (Is_Inlined (Pack)
or else Is_Generic_Instance (Pack)
-   or else Is_Internal (E))
+   or else Nkind (Decl) = N_Subprogram_Body
+   or else Present (Corresponding_Body (Decl)))
 and then not In_Main_Unit_Or_Subunit (E)
 and then not Is_Nested (E)
 and then not Has_Initialized_Type (E)


[Ada] Type conversion to String causes Constraint_Error

2014-11-20 Thread Arnaud Charlet
This patch modifies the mechanism which creates a subtype from an arbitrary
expression. The mechanism now captures the bounds of all index constraints
when the expression is of an array type.


-- Source --


--  pack.ads

with Ada.Finalization; use Ada.Finalization;

package Pack is
   type Ctrl is new Controlled with record
  Flag : Boolean := False;
   end record;

   type New_String is new String;

   function Make_Ctrl return Ctrl;
   function Make_String (Val : String) return New_String;
end Pack;

--  pack.adb

package body Pack is
   function Make_Ctrl return Ctrl is
  Result : Ctrl;
   begin
  return Result;
   end Make_Ctrl;

   function Make_String (Val : String) return New_String is
   begin
  return New_String (Val);
   end Make_String;
end Pack;

--  pack2.ads

package Pack2 is
   procedure Reproduce;
end Pack2;

--  pack2.adb

with Ada.Text_IO; use Ada.Text_IO;
with Pack;use Pack;

package body Pack2 is
   Str : constant New_String := Make_String (Hello);
   Ctr : constant Ctrl := Make_Ctrl;

   procedure Reproduce is
   begin
  Put_Line (String (Str));
   end Reproduce;
end Pack2;

--  main.adb

with Pack2; use Pack2;

procedure Main is
begin
   Reproduce;
end Main;


-- Compilation and output --


$ gnatmake -q main.adb
$ ./main
Hello

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

2014-11-20  Hristian Kirtchev  kirtc...@adacore.com

* exp_util.adb (Make_Subtype_From_Expr): Capture the bounds of
all index constracts when the expression is of an array type.

Index: exp_util.adb
===
--- exp_util.adb(revision 217854)
+++ exp_util.adb(working copy)
@@ -6399,22 +6399,24 @@
  (E   : Node_Id;
   Unc_Typ : Entity_Id) return Node_Id
is
+  List_Constr : constant List_Id:= New_List;
   Loc : constant Source_Ptr := Sloc (E);
-  List_Constr : constant List_Id:= New_List;
   D   : Entity_Id;
+  Full_Exp: Node_Id;
+  Full_Subtyp : Entity_Id;
+  High_Bound  : Entity_Id;
+  Index_Typ   : Entity_Id;
+  Low_Bound   : Entity_Id;
+  Priv_Subtyp : Entity_Id;
+  Utyp: Entity_Id;
 
-  Full_Subtyp  : Entity_Id;
-  Priv_Subtyp  : Entity_Id;
-  Utyp : Entity_Id;
-  Full_Exp : Node_Id;
-
begin
   if Is_Private_Type (Unc_Typ)
 and then Has_Unknown_Discriminants (Unc_Typ)
   then
- --  Prepare the subtype completion, Go to base type to
- --  find underlying type, because the type may be a generic
- --  actual or an explicit subtype.
+ --  Prepare the subtype completion. Use the base type to find the
+ --  underlying type because the type may be a generic actual or an
+ --  explicit subtype.
 
  Utyp:= Underlying_Type (Base_Type (Unc_Typ));
  Full_Subtyp := Make_Temporary (Loc, 'C');
@@ -6451,22 +6453,67 @@
  return New_Occurrence_Of (Priv_Subtyp, Loc);
 
   elsif Is_Array_Type (Unc_Typ) then
+ Index_Typ := First_Index (Unc_Typ);
  for J in 1 .. Number_Dimensions (Unc_Typ) loop
-Append_To (List_Constr,
-  Make_Range (Loc,
-Low_Bound =
+
+--  Capture the bounds of each index constraint in case the context
+--  is an object declaration of an unconstrained type initialized
+--  by a function call:
+
+--Obj : Unconstr_Typ := Func_Call;
+
+--  This scenario requires secondary scope management and the index
+--  constraint cannot depend on the temporary used to capture the
+--  result of the function call.
+
+--SS_Mark;
+--Temp : Unconstr_Typ_Ptr := Func_Call'reference;
+--subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
+--Obj : S := Temp.all;
+--SS_Release;  --  Temp is gone at this point, bounds of S are
+-- --  non existent.
+
+--  The bounds are kept as variables rather than constants because
+--  this prevents spurious optimizations down the line.
+
+--  Generate:
+--Low_Bound : Base_Type (Index_Typ) := E'First (J);
+
+Low_Bound := Make_Temporary (Loc, 'B');
+Insert_Action (E,
+  Make_Object_Declaration (Loc,
+Defining_Identifier = Low_Bound,
+Object_Definition   =
+  New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
+Expression  =
   Make_Attribute_Reference (Loc,
-Prefix = Duplicate_Subexpr_No_Checks (E),
+Prefix = Duplicate_Subexpr_No_Checks (E),
 Attribute_Name = Name_First,
-

[Ada] Debugging information for inlined predefined units

2014-11-20 Thread Arnaud Charlet
The compiler suppresses debugging information on predefined units that are
inlined in the code, because stepping into run-time units often complicates
debugging activity. We  make an exception for calls that appear in the source,
when the unit is part of the Ada hierarchy, to facilitate monitoring of storage
management.

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

2014-11-20  Ed Schonberg  schonb...@adacore.com

* exp_ch6.adb (Expand_Call, Inlined_Subprogram): Do not suppress
debugging information for a call to a predefined unit, if the
call comes from source and the unit is in the Ada hierarchy.

Index: exp_ch6.adb
===
--- exp_ch6.adb (revision 217828)
+++ exp_ch6.adb (working copy)
@@ -3720,7 +3720,17 @@
  (Unit_File_Name (Get_Source_Unit (Sloc (Subp
   and then In_Extended_Main_Source_Unit (N)
 then
-   Set_Needs_Debug_Info (Subp, False);
+   --  We make an exception for calls to the Ada hierarchy if call
+   --  comes from source, because some user applications need the
+   --  debugging information for such calls.
+
+   if Comes_From_Source (Call_Node)
+ and then Name_Buffer (1 .. 2) = a-
+   then
+  null;
+   else
+  Set_Needs_Debug_Info (Subp, False);
+   end if;
 end if;
 
  --  Front end expansion of simple functions returning unconstrained


[Ada] Improvements to handling of unchecked union discriminants

2014-11-20 Thread Arnaud Charlet
This patch avoids issuing a warning for a missing component clause
for a discriminant in an unchecked union, and also avoids printing
a line for such a component in the -gnatR2 output.

The following program:

 1. with Interfaces;
 2. procedure Test_Union is
 3.   type Test_Type (Flag : Boolean) is
 4. record
 5.   case Flag is
 6. when True =
 7.   Thing_1 : Interfaces.Unsigned_32;
 8. when False =
 9.   Thing_2 : Interfaces.Unsigned_32;
10.   end case;
11. end record
12. with Unchecked_Union;
13.   for Test_Type use
14. record
15.   Thing_1 at 0 range 0 .. 31;
16.   Thing_2 at 0 range 0 .. 31;
17.   end record;
18.pragma Unreferenced (Test_Type);
19. begin
20.   null;
21. end Test_Union;

compiles quietly with switches -gnatwa -gnatR2, and generates
this representation output:

Representation information for unit Test_Union (body)

for Test_Type'Size use 32;
for Test_Type'Alignment use 4;
for Test_Type use record
   Thing_1 at 0 range  0 .. 31;
   Thing_2 at 0 range  0 .. 31;
end record;

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

2014-11-20  Robert Dewar  de...@adacore.com

* repinfo.adb (List_Record_Info): Do not list discriminant in
unchecked union.
* sem_ch13.adb (Has_Good_Profile): Minor reformatting
(Analyze_Stream_TSS_Definition): Minor reformatting
(Analyze_Record_Representation_Clause): Do not issue warning
for missing rep clause for discriminant in unchecked union.

Index: repinfo.adb
===
--- repinfo.adb (revision 217828)
+++ repinfo.adb (working copy)
@@ -847,37 +847,49 @@
 
   Comp := First_Component_Or_Discriminant (Ent);
   while Present (Comp) loop
- Get_Decoded_Name_String (Chars (Comp));
- Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len);
 
- Cfbit := Component_Bit_Offset (Comp);
+ --  Skip discriminant in unchecked union (since it is not there!)
 
- if Rep_Not_Constant (Cfbit) then
-UI_Image_Length := 2;
+ if Ekind (Comp) = E_Discriminant
+   and then Is_Unchecked_Union (Ent)
+ then
+null;
 
+ --  All other cases
+
  else
---  Complete annotation in case not done
+Get_Decoded_Name_String (Chars (Comp));
+Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len);
 
-Set_Normalized_Position (Comp, Cfbit / SSU);
-Set_Normalized_First_Bit (Comp, Cfbit mod SSU);
+Cfbit := Component_Bit_Offset (Comp);
 
-Sunit := Cfbit / SSU;
-UI_Image (Sunit);
- end if;
+if Rep_Not_Constant (Cfbit) then
+   UI_Image_Length := 2;
 
- --  If the record is not packed, then we know that all fields whose
- --  position is not specified have a starting normalized bit position
- --  of zero.
+else
+   --  Complete annotation in case not done
 
- if Unknown_Normalized_First_Bit (Comp)
-   and then not Is_Packed (Ent)
- then
-Set_Normalized_First_Bit (Comp, Uint_0);
+   Set_Normalized_Position (Comp, Cfbit / SSU);
+   Set_Normalized_First_Bit (Comp, Cfbit mod SSU);
+
+   Sunit := Cfbit / SSU;
+   UI_Image (Sunit);
+end if;
+
+--  If the record is not packed, then we know that all fields
+--  whose position is not specified have a starting normalized
+--  bit position of zero.
+
+if Unknown_Normalized_First_Bit (Comp)
+  and then not Is_Packed (Ent)
+then
+   Set_Normalized_First_Bit (Comp, Uint_0);
+end if;
+
+Max_Suni_Length :=
+  Natural'Max (Max_Suni_Length, UI_Image_Length);
  end if;
 
- Max_Suni_Length :=
-   Natural'Max (Max_Suni_Length, UI_Image_Length);
-
  Next_Component_Or_Discriminant (Comp);
   end loop;
 
@@ -885,6 +897,17 @@
 
   Comp := First_Component_Or_Discriminant (Ent);
   while Present (Comp) loop
+
+ --  Skip discriminant in unchecked union (since it is not there!)
+
+ if Ekind (Comp) = E_Discriminant
+   and then Is_Unchecked_Union (Ent)
+ then
+goto Continue;
+ end if;
+
+ --  All other cases
+
  declare
 Esiz : constant Uint := Esize (Comp);
 Bofs : constant Uint := Component_Bit_Offset (Comp);
Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 217857)
+++ sem_ch13.adb(working copy)
@@ -3555,7 +3555,7 @@
 
 if  Base_Type (Typ) = Base_Type (Ent)
   or else (Is_Class_Wide_Type (Typ)

[Ada] Source in multi-unit source has unique object file name

2014-11-20 Thread Arnaud Charlet
Two units, one in a multi-source file and one in another source with
the same base file name do not have the same object file name.

No error during processing of the following project file should be
reported:

project Prj is
   package Naming is
  for Spec (foo_bar) use foo_bar.ads at 2;
  for Spec (foo_bar_types) use foo_bar.ads at 1;
  for Body (foo_bar) use foo_bar.adb;
   end Naming;
end Prj;

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

2014-11-20  Vincent Celier  cel...@adacore.com

* prj-nmsc.adb (Check_Object): If a unit is in a multi-source
file, its object file is never the same as any other unit.

Index: prj-nmsc.adb
===
--- prj-nmsc.adb(revision 217874)
+++ prj-nmsc.adb(working copy)
@@ -2577,7 +2577,7 @@
 Error_Msg_Name_1 := Lang_Index.Display_Name;
 Error_Msg
   (Data.Flags,
-   ?no compiler specified for language %% 
+   ?\no compiler specified for language %% 
  , ignoring all its sources,
No_Location, Project);
 
@@ -2604,7 +2604,7 @@
 if Lang_Index.Config.Naming_Data.Spec_Suffix = No_File then
Error_Msg
  (Data.Flags,
-  Spec_Suffix not specified for  
+  \Spec_Suffix not specified for  
   Get_Name_String (Lang_Index.Name),
   No_Location, Project);
 end if;
@@ -2612,7 +2612,7 @@
 if Lang_Index.Config.Naming_Data.Body_Suffix = No_File then
Error_Msg
  (Data.Flags,
-  Body_Suffix not specified for  
+  \Body_Suffix not specified for  
   Get_Name_String (Lang_Index.Name),
   No_Location, Project);
 end if;
@@ -2630,7 +2630,7 @@
Error_Msg_Name_1 := Lang_Index.Display_Name;
Error_Msg
  (Data.Flags,
-  no suffixes specified for %%,
+  \no suffixes specified for %%,
   No_Location, Project);
 end if;
  end if;
@@ -3770,7 +3770,7 @@
if Switches /= No_Array_Element then
   Error_Msg
 (Data.Flags,
- ?Linker switches not taken into account in library  
+ ?\Linker switches not taken into account in library  
  projects,
  No_Location, Project);
end if;
@@ -6793,7 +6793,7 @@
 Error_Msg_Name_2 := Source.Unit.Name;
 Error_Or_Warning
   (Data.Flags, Data.Flags.Missing_Source_Files,
-   source file %% for unit %% not found,
+   \source file %% for unit %% not found,
No_Location, Project.Project);
  end if;
   end if;
@@ -7789,7 +7789,7 @@
 Error_Msg_File_1 := Source.File;
 Error_Msg
   (Data.Flags,
-   { cannot be both excluded and an exception file name,
+   \{ cannot be both excluded and an exception file name,
No_Location, Project.Project);
  end if;
 
@@ -7936,13 +7936,15 @@
  if Source /= No_Source
and then Source.Replaced_By = No_Source
and then Source.Path /= Src.Path
+   and then Source.Index = 0
+   and then Src.Index = 0
and then Is_Extending (Src.Project, Source.Project)
  then
 Error_Msg_File_1 := Src.File;
 Error_Msg_File_2 := Source.File;
 Error_Msg
   (Data.Flags,
-   { and { have the same object file name,
+   \{ and { have the same object file name,
No_Location, Project.Project);
 
  else


[Ada] PR ada/63931

2014-11-20 Thread Arnaud Charlet
Fixing version number according to new GCC naming scheme.

PR ada/63931   
* gnatvsn.ads (Library_Version): Switch to 5.

Index: gnatvsn.ads
===
--- gnatvsn.ads (revision 217874)
+++ gnatvsn.ads (working copy)
@@ -82,7 +82,7 @@
--  Prefix generated by binder. If it is changed, be sure to change
--  GNAT.Compiler_Version.Ver_Prefix as well.
 
-   Library_Version : constant String := 5.0;
+   Library_Version : constant String := 5;
--  Library version. This value must be updated when the compiler
--  version number Gnat_Static_Version_String is updated.
--


[Ada] New internal primitive Is_Subprogram_Or_Generic_Subprogram

2014-10-10 Thread Arnaud Charlet
This is a minor internal cleanup, to introduce a new primitive
Is_Subprogram_Or_Generic_Subprogram with the obvious meaning.
No external effect, no test required.

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

2014-10-10  Robert Dewar  de...@adacore.com

* sem_ch7.adb, einfo.adb, einfo.ads, sem_prag.adb, sem_ch12.adb,
freeze.adb, sem_util.adb, sem_res.adb, exp_ch6.adb, exp_ch13.adb,
sem_ch6.adb, sem_cat.adb, sem_disp.adb
(Is_Subprogram_Or_Generic_Subprogram): New primitive. Use this primitive
throughout where appropriate.

Index: sem_ch7.adb
===
--- sem_ch7.adb (revision 216063)
+++ sem_ch7.adb (working copy)
@@ -2808,7 +2808,7 @@
 
   --  Body required if subprogram
 
-  elsif Is_Subprogram (P) or else Is_Generic_Subprogram (P) then
+  elsif Is_Subprogram_Or_Generic_Subprogram (P) then
  return True;
 
   --  Treat a block as requiring a body
@@ -2937,7 +2937,7 @@
 
   --  Body required if subprogram
 
-  elsif Is_Subprogram (P) or else Is_Generic_Subprogram (P) then
+  elsif Is_Subprogram_Or_Generic_Subprogram (P) then
  Error_Msg_N (info:  requires body (subprogram case)?Y?, P);
 
   --  Body required if generic parent has Elaborate_Body
Index: einfo.adb
===
--- einfo.adb   (revision 216063)
+++ einfo.adb   (working copy)
@@ -1129,8 +1129,7 @@
E_Package_Body,
E_Subprogram_Body,
E_Variable)
-  or else Is_Generic_Subprogram (Id)
-  or else Is_Subprogram (Id));
+  or else Is_Subprogram_Or_Generic_Subprogram (Id));
   return Node34 (Id);
end Contract;
 
@@ -3405,6 +3404,13 @@
   return Ekind (Id) in Subprogram_Kind;
end Is_Subprogram;
 
+   function Is_Subprogram_Or_Generic_Subprogram (Id : E) return B is
+   begin
+  return Ekind (Id) in Subprogram_Kind
+   or else
+ Ekind (Id) in Generic_Subprogram_Kind;
+   end Is_Subprogram_Or_Generic_Subprogram;
+
function Is_Task_Type(Id : E) return B is
begin
   return Ekind (Id) in Task_Kind;
@@ -3593,15 +3599,14 @@
begin
   pragma Assert
 (Ekind_In (Id, E_Entry,
- E_Entry_Family,
- E_Generic_Package,
- E_Package,
- E_Package_Body,
- E_Subprogram_Body,
- E_Variable,
- E_Void)
- or else Is_Generic_Subprogram (Id)
- or else Is_Subprogram (Id));
+ E_Entry_Family,
+ E_Generic_Package,
+ E_Package,
+ E_Package_Body,
+ E_Subprogram_Body,
+ E_Variable,
+ E_Void)
+  or else Is_Subprogram_Or_Generic_Subprogram (Id));
   Set_Node34 (Id, V);
end Set_Contract;
 
Index: einfo.ads
===
--- einfo.ads   (revision 216063)
+++ einfo.ads   (working copy)
@@ -2974,6 +2974,10 @@
 --   Applies to all entities, true for function, procedure and operator
 --   entities.
 
+--Is_Subprogram_Or_Generic_Subprogram
+--   Applies to all entities, true for function procedure and operator
+--   entities, and also for the corresponding generic entities.
+
 --Is_Synchronized_Interface (synthesized)
 --   Defined in types that are interfaces. True if interface is declared
 --   synchronized, task, or protected, or is derived from a synchronized
@@ -6964,6 +6968,7 @@
function Is_Scalar_Type  (Id : E) return B;
function Is_Signed_Integer_Type  (Id : E) return B;
function Is_Subprogram   (Id : E) return B;
+   function Is_Subprogram_Or_Generic_Subprogram (Id : E) return B;
function Is_Task_Type(Id : E) return B;
function Is_Type (Id : E) return B;
 
@@ -8800,6 +8805,7 @@
pragma Inline (Is_Base_Type);
pragma Inline (Is_Package_Or_Generic_Package);
pragma Inline (Is_Packed_Array);
+   pragma Inline (Is_Subprogram_Or_Generic_Subprogram);
pragma Inline (Is_Volatile);
pragma Inline (Is_Wrapper_Package);
pragma Inline (Known_RM_Size);
Index: sem_prag.adb
===
--- sem_prag.adb(revision 216063)
+++ sem_prag.adb(working copy)
@@ -6736,10 +6736,9 @@
 (dispatching subprogram# cannot use Stdcall convention!,
  Arg1);
 
-   --  Subprogram is allowed, but not a generic subprogram
+   --  Subprograms are not allowed
 
-   elsif not Is_Subprogram (E)
- and then not Is_Generic_Subprogram (E)
+   elsif not Is_Subprogram_Or_Generic_Subprogram (E)
 

[Ada] Check for attempt to bind GNATprove files

2014-10-10 Thread Arnaud Charlet
If one or more objects is compiled in GNATprove mode (either by using
GNATprove directly, or by using -gnatd.F), then the ALI file is marked
and gnatbind will exit with a message as shown here. Given:

 1. procedure linkdf is
 2. begin
 3.null;
 4. end;

If we first compile this with

  gcc -c linkdf.adb -gnatd.F

then we try to do a gnatmake, we get

error: one or more files compiled in GNATprove mode
gnatmake: *** bind failed.

Previously this was not detected and the linker bombed
with peculiar error messages.

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

2014-10-10  Robert Dewar  de...@adacore.com

* ali.adb (Scan_ALI): Read and process new GP flag on ALI P line.
* ali.ads (GNATprove_Mode): New component in ALI table.
(GNATprove_Mode_Specified): New global.
* gnatbind.adb (Gnatbind): Give fatal error if any file compiled
in GNATProve mode.
* lib-writ.ads, lib-writ.adb (GP): New flag on P line for
GNATProve_Mode.

Index: lib-writ.adb
===
--- lib-writ.adb(revision 216063)
+++ lib-writ.adb(working copy)
@@ -1153,6 +1153,10 @@
  end if;
   end if;
 
+  if GNATprove_Mode then
+ Write_Info_Str ( GP);
+  end if;
+
   if Partition_Elaboration_Policy /= ' ' then
  Write_Info_Str  ( E);
  Write_Info_Char (Partition_Elaboration_Policy);
Index: lib-writ.ads
===
--- lib-writ.ads(revision 216063)
+++ lib-writ.ads(working copy)
@@ -192,6 +192,9 @@
--  the units in this file, where x is the first character
--  (upper case) of the policy name (e.g. 'C' for Concurrent).
 
+   -- GP   Set if this compilation was done in GNATprove mode, either
+   --  from direct use of GNATprove, or from use of -gnatdF.
+
-- Lx   A valid Locking_Policy pragma applies to all the units in
--  this file, where x is the first character (upper case) of
--  the policy name (e.g. 'C' for Ceiling_Locking).
@@ -200,7 +203,9 @@
--  were not compiled to produce an object. This can occur as a
--  result of the use of -gnatc, or if no object can be produced
--  (e.g. when a package spec is compiled instead of the body,
-   --  or a subunit on its own).
+   --  or a subunit on its own). Note that in GNATprove mode, we
+   --  do produce an object. The object is not suitable for binding
+   --  and linking, but we do not set NO, instead we set GP.
 
-- NR   No_Run_Time. Indicates that a pragma No_Run_Time applies
--  to all units in the file.
Index: ali.adb
===
--- ali.adb (revision 216063)
+++ ali.adb (working copy)
@@ -111,6 +111,7 @@
   Locking_Policy_Specified   := ' ';
   No_Normalize_Scalars_Specified := False;
   No_Object_Specified:= False;
+  GNATprove_Mode_Specified   := False;
   Normalize_Scalars_Specified:= False;
   Partition_Elaboration_Policy_Specified := ' ';
   Queuing_Policy_Specified   := ' ';
@@ -875,6 +876,7 @@
 First_Sdep   = No_Sdep_Id,
 First_Specific_Dispatching   = Specific_Dispatching.Last + 1,
 First_Unit   = No_Unit_Id,
+GNATprove_Mode   = False,
 Last_Interrupt_State = Interrupt_States.Last,
 Last_Sdep= No_Sdep_Id,
 Last_Specific_Dispatching= Specific_Dispatching.Last,
@@ -1089,6 +1091,13 @@
ALIs.Table (Id).Partition_Elaboration_Policy :=
  Partition_Elaboration_Policy_Specified;
 
+--  Processing for GP
+
+elsif C = 'G' then
+   Checkc ('P');
+   GNATprove_Mode_Specified := True;
+   ALIs.Table (Id).GNATprove_Mode := True;
+
 --  Processing for Lx
 
 elsif C = 'L' then
Index: ali.ads
===
--- ali.ads (revision 216063)
+++ ali.ads (working copy)
@@ -176,6 +176,11 @@
   --  always be set as well in this case. Not set if 'P' appears in
   --  Ignore_Lines.
 
+  GNATprove_Mode : Boolean;
+  --  Set to True if ALI and object file produced in GNATprove_Mode as
+  --  signalled by GP appearing on the P line. Not set if 'P' appears in
+  --  Ignore_Lines.
+
   No_Object : Boolean;
   --  Set to True if no object file generated. Not set if 'P' appears in
   --  Ignore_Lines.
@@ -465,6 +470,9 @@
--  Set to False by Initialize_ALI. Set to True if Scan_ALI reads
--  a unit for which dynamic elaboration 

[Ada] Issue errors on illegal contracts unless SPARK_Mode is Off

2014-10-10 Thread Arnaud Charlet
Illegal Global/Depends contracts should be flagged by frontend in code for
which SPARK_Mode is not specified, as GNATprove relies on contracts being
legal in those cases. The frontend should skip these errors only when
SPARK_Mode is Off. Now fixed, as shown on the following example.

Command:

$ gcc -c notinspark.ads

Output:
---
 1. package Notinspark is
 2.
 3.function Get return Integer;
 4.
 5.procedure Set with
 6.  Global = (In_Out = Get);
  |
 global item must denote variable or state

 7.
 8. end Notinspark;

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

2014-10-10  Yannick Moy  m...@adacore.com

* errout.adb (SPARK_Msg_N): Issue error unless SPARK_Mode is Off.

Index: errout.adb
===
--- errout.adb  (revision 216063)
+++ errout.adb  (working copy)
@@ -3138,7 +3138,7 @@
 
procedure SPARK_Msg_N (Msg : String; N : Node_Or_Entity_Id) is
begin
-  if SPARK_Mode = On then
+  if SPARK_Mode /= Off then
  Error_Msg_N (Msg, N);
   end if;
end SPARK_Msg_N;


[Ada] Loop parameter is a constant in an iterator over a formal container.

2014-10-10 Thread Arnaud Charlet
This patch enforces the same semantics for the handling of loop parameters
in element iterators over formal containers, os those over formal containers:
the loop parameter cannot be assigned to in user code.

Compiling formal_test.adb must yield:

   formal_test.adb:15:07: assignment to loop parameter not allowed

---
with Ada.Containers.Formal_Doubly_Linked_Lists;
procedure Formal_Test is
   type E is range 1 .. 1000;
   package My_List is new Ada.Containers.Formal_Doubly_Linked_Lists (E);
   use My_List;
   Thing : My_List.List (10);
   C : Cursor;
begin
   for I in 1 .. 10 loop
  Append (Thing, E (I));
   end loop;

   for Element of Thing loop
  null;
  Element := Element * 3;  --  ERROR
   end loop;
end;

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

2014-10-10  Ed Schonberg  schonb...@adacore.com

* exp_ch5.adb (Expand_Formal_Container_Element_Loop): Analyze
declaration for loop parameter before rest of loop, and set
entity kind to prevent assignments to it in the user code.
* sem_ch3.adb (Analyze_Object_Contract): No contracts apply to the
loop parameter in an element iteration over o formal container.

Index: exp_ch5.adb
===
--- exp_ch5.adb (revision 216063)
+++ exp_ch5.adb (working copy)
@@ -2889,7 +2889,17 @@
   Statements =  New_List (New_Loop)));
 
   Rewrite (N, New_Loop);
-  Analyze (New_Loop);
+
+  --  The loop parameter is declared by an object declaration, but within
+  --  the loop we must prevent user assignments to it, so we analyze the
+  --  declaration and reset the entity kind, before analyzing the rest of
+  --  the loop;
+
+  Analyze (Elmt_Decl);
+  Set_Ekind (Defining_Identifier (Elmt_Decl), E_Loop_Parameter);
+  Set_Assignment_OK (Name (Elmt_Ref));
+
+  Analyze (N);
end Expand_Formal_Container_Element_Loop;
 
-
Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 216063)
+++ sem_ch3.adb (working copy)
@@ -3062,6 +3062,12 @@
 Error_Msg_N (constant cannot be volatile, Obj_Id);
  end if;
 
+  --  The loop parameter in an element iterator over a formal container
+  --  is declared with an object declaration but no contracts apply.
+
+  elsif Ekind (Obj_Id) = E_Loop_Parameter then
+ null;
+
   else pragma Assert (Ekind (Obj_Id) = E_Variable);
 
  --  The following checks are only relevant when SPARK_Mode is on as


[Ada] Operator name returned by GNAT.Source_Info.Enclosing_Entity

2014-10-10 Thread Arnaud Charlet
The string returned by GNAT.Source_Info.Enclosing_Entity did not include
names of operators (e.g. **).

The following program:

 1. with Text_IO; use Text_IO;
 2. with GNAT.Source_Info; use GNAT.Source_Info;
 3. procedure BadEE is
 4.type R is new Boolean;
 5.RV : R := True;
 6.
 7.function ** (X, Y : R) return String is
 8.begin
 9.   return Enclosing_Entity;
10.end;
11. begin
12.Put_Line (RV ** RV);
13. end BadEE;

must output the string:

BadEE.**

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

2014-10-10  Robert Dewar  de...@adacore.com

* exp_intr.adb (Write_Entity_Name): Moved to outer level
(Write_Entity_Name): Properly handle operator names
(Expand_Source_Info): New procedure.
* exp_intr.ads (Add_Source_Info): New procedure.

Index: exp_intr.adb
===
--- exp_intr.adb(revision 216063)
+++ exp_intr.adb(working copy)
@@ -36,7 +36,6 @@
 with Exp_Fixd; use Exp_Fixd;
 with Exp_Util; use Exp_Util;
 with Freeze;   use Freeze;
-with Namet;use Namet;
 with Nmake;use Nmake;
 with Nlists;   use Nlists;
 with Opt;  use Opt;
@@ -116,6 +115,96 @@
--Name_Compilation_Date  - expand string with compilation date
--Name_Compilation_Time  - expand string with compilation time
 
+   procedure Write_Entity_Name (E : Entity_Id);
+   --  Recursive procedure to construct string for qualified name of enclosing
+   --  program unit. The qualification stops at an enclosing scope has no
+   --  source name (block or loop). If entity is a subprogram instance, skip
+   --  enclosing wrapper package. The name is appended to the current contents
+   --  of Name_Buffer, incrementing Name_Len.
+
+   -
+   -- Add_Source_Info --
+   -
+
+   procedure Add_Source_Info (Loc : Source_Ptr; Nam : Name_Id) is
+  Ent : Entity_Id;
+
+  Save_NB : constant String  := Name_Buffer (1 .. Name_Len);
+  Save_NL : constant Natural := Name_Len;
+  --  Save current Name_Buffer contents
+
+   begin
+  Name_Len := 0;
+
+  --  Line
+
+  case Nam is
+
+ when Name_Line =
+Add_Nat_To_Name_Buffer (Nat (Get_Logical_Line_Number (Loc)));
+
+ when Name_File =
+Get_Decoded_Name_String
+  (Reference_Name (Get_Source_File_Index (Loc)));
+
+ when Name_Source_Location =
+Build_Location_String (Loc);
+
+ when Name_Enclosing_Entity =
+
+--  Skip enclosing blocks to reach enclosing unit
+
+Ent := Current_Scope;
+while Present (Ent) loop
+   exit when Ekind (Ent) /= E_Block
+ and then Ekind (Ent) /= E_Loop;
+   Ent := Scope (Ent);
+end loop;
+
+--  Ent now points to the relevant defining entity
+
+Write_Entity_Name (Ent);
+
+ when Name_Compilation_Date =
+declare
+   subtype S13 is String (1 .. 3);
+   Months : constant array (1 .. 12) of S13 :=
+  (Jan, Feb, Mar, Apr, May, Jun,
+   Jul, Aug, Sep, Oct, Nov, Dec);
+
+   M1 : constant Character := Opt.Compilation_Time (6);
+   M2 : constant Character := Opt.Compilation_Time (7);
+
+   MM : constant Natural range 1 .. 12 :=
+  (Character'Pos (M1) - Character'Pos ('0')) * 10 +
+ (Character'Pos (M2) - Character'Pos ('0'));
+
+begin
+   --  Reformat ISO date into MMM DD  (__DATE__) format
+
+   Name_Buffer (1 .. 3)  := Months (MM);
+   Name_Buffer (4)   := ' ';
+   Name_Buffer (5 .. 6)  := Opt.Compilation_Time (9 .. 10);
+   Name_Buffer (7)   := ' ';
+   Name_Buffer (8 .. 11) := Opt.Compilation_Time (1 .. 4);
+   Name_Len := 11;
+end;
+
+ when Name_Compilation_Time =
+Name_Buffer (1 .. 8) := Opt.Compilation_Time (12 .. 19);
+Name_Len := 8;
+
+ when others =
+raise Program_Error;
+  end case;
+
+  --  Prepend original Name_Buffer contents
+
+  Name_Buffer (Save_NL + 1 .. Save_NL + Name_Len) :=
+Name_Buffer (1 .. Name_Len);
+  Name_Buffer (1 .. Save_NL) := Save_NB;
+   end Add_Source_Info;
+
-
-- Expand_Binary_Operator_Call --
-
@@ -718,61 +807,6 @@
   Loc : constant Source_Ptr := Sloc (N);
   Ent : Entity_Id;
 
-  procedure Write_Entity_Name (E : Entity_Id);
-  --  Recursive procedure to construct string for qualified name of
-  --  enclosing program unit. The qualification stops at an enclosing
-  --  scope has no source name (block or loop). If entity is a subprogram
-  --  instance, skip 

[Ada] Implement new pragma Prefix_Exception_Messages

2014-10-10 Thread Arnaud Charlet
This implements a new configuration pragma

pragma Prefix_Exception_Messages;

which causes messages set using raise x with s to be
prefixed by the expanded name of the enclosing entity if
s is a string literal (if s is more complex, we assume
the program is calculating exactly the message it wants).

So for example, if we have the program:

  1. pragma Prefix_Exception_Messages;
  2. procedure Prefixem is
  3.procedure Inner is
  4.begin
  5.   raise Constraint_Error with explicit raise;
  6.end;
  7. begin
  8.Inner;
  9. end Prefixem;

The output will be:

raised CONSTRAINT_ERROR : Prefixem.Inner: explicit raise

This mode is automatic for run-time library files, so
a typical message from the runtime library which used to
look like:

raised GNAT.CALENDAR.TIME_IO.PICTURE_ERROR :
null picture string

now looks like:

raised GNAT.CALENDAR.TIME_IO.PICTURE_ERROR :
GNAT.Calendar.Time_IO.Image: null picture string

In the case of instantiations of containers, you will get the full
qualified name of the particular instantiation that is involved. For
example, the following program:

  1. with Ada.Containers.Ordered_Sets;
  2. procedure NoElmt is
  3.package Ordered_Integer_Sets is
  4.  new Ada.Containers.Ordered_Sets (Integer);
  5.use Ordered_Integer_Sets;
  6. begin
  7.if No_Element  No_Element then
  8.   null;
  9.end if;
 10. end;

will output

raised CONSTRAINT_ERROR :
NoElmt.Ordered_Integer_Sets.: Left cursor equals No_Element

This allows disambiguation of messages without reintroducing
line numbers which are problematic for maintaining tests over
different versions and targets.

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

2014-10-10  Robert Dewar  de...@adacore.com

* exp_ch11.adb (Expand_N_Raise_Statement): Handle
Prefix_Exception_Messages.
* opt.adb: Handle new flags Prefix_Exception_Message[_Config].
* opt.ads: New flags Prefix_Exception_Message[_Config].
* par-prag.adb: New dummy entry for pragma Prefix_Exception_Messages.
* snames.ads-tmpl: Add entries for new pragma Prefix_Exception_Messages.
* sem_prag.adb: Implement new pragma Prefix_Exception_Messages
* gnat_rm.texi: Document pragma Prefix_Exception_Messages.

Index: exp_ch11.adb
===
--- exp_ch11.adb(revision 216063)
+++ exp_ch11.adb(working copy)
@@ -29,6 +29,7 @@
 with Elists;   use Elists;
 with Errout;   use Errout;
 with Exp_Ch7;  use Exp_Ch7;
+with Exp_Intr; use Exp_Intr;
 with Exp_Util; use Exp_Util;
 with Namet;use Namet;
 with Nlists;   use Nlists;
@@ -1565,6 +1566,22 @@
 
   if Present (Expression (N)) then
 
+ --  Adjust message to deal with Prefix_Exception_Messages. We only
+ --  add the prefix to string literals, if the message is being
+ --  constructed, we assume it already deals with uniqueness.
+
+ if Prefix_Exception_Messages
+   and then Nkind (Expression (N)) = N_String_Literal
+ then
+Name_Len := 0;
+Add_Source_Info (Loc, Name_Enclosing_Entity);
+Add_Str_To_Name_Buffer (: );
+Add_String_To_Name_Buffer (Strval (Expression (N)));
+Rewrite (Expression (N),
+  Make_String_Literal (Loc, Name_Buffer (1 .. Name_Len)));
+Analyze_And_Resolve (Expression (N), Standard_String);
+ end if;
+
  --  Avoid passing exception-name'identity in runtimes in which this
  --  argument is not used. This avoids generating undefined references
  --  to these exceptions when compiling with no optimization
Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 216081)
+++ gnat_rm.texi(working copy)
@@ -227,6 +227,7 @@
 * Pragma Precondition::
 * Pragma Predicate::
 * Pragma Preelaborable_Initialization::
+* Pragma Prefix_Exception_Messages::
 * Pragma Pre_Class::
 * Pragma Priority_Specific_Dispatching::
 * Pragma Profile::
@@ -1096,6 +1097,7 @@
 * Pragma Precondition::
 * Pragma Predicate::
 * Pragma Preelaborable_Initialization::
+* Pragma Prefix_Exception_Messages::
 * Pragma Pre_Class::
 * Pragma Priority_Specific_Dispatching::
 * Pragma Profile::
@@ -5692,6 +5694,34 @@
 versions of Ada as an implementation-defined pragma.
 See Ada 2012 Reference Manual for details.
 
+@node Pragma Prefix_Exception_Messages
+@unnumberedsec Pragma Prefix_Exception_Messages
+@cindex Prefix_Exception_Messages
+@cindex exception
+@cindex Exception_Message
+@findex Exceptions
+@noindent
+Syntax:
+
+@smallexample @c ada
+pragma Prefix_Exception_Messages;
+@end smallexample
+
+@noindent
+This is an implementation-defined configuration pragma that affects the
+behavior of raise statements with a message given as a static string
+constant (typically a 

[Ada] Spurious error on local instantiation of pure generic unit

2014-10-10 Thread Arnaud Charlet
This patch fixes an error in the legality checks of aspects that apply
to library units: these aspects are legal on a local instantiation of a
library-level generic unit that carries the aspect pure.

The following must compile quietly:

   gcc -c my_buffer.adb

---
package My_Buffer
  with Elaborate_Body
is
end My_Buffer;
---
with Common.Gen_Circular_Buffer;
package body My_Buffer is
   type Capacity_Count is range 0 .. 10;

   procedure Copy_Integer
 (From_Element : in Integer;
  To_Element   :out Integer)
   is
   begin
  To_Element := From_Element;
   end Copy_Integer;

   package Buffer is new
 Common.Gen_Circular_Buffer (Capacity_Count = Capacity_Count,
 Capacity   = 10,
 Element_Type   = Integer,
 Copy_Element   = Copy_Integer);
end My_Buffer;
---
package body Common.Gen_Circular_Buffer is
   procedure Initialize (Buffer : out Buffer_Type) is
   begin
  Buffer.Start_Index := Element_Index'First;
  Buffer.Count   := 0;
   end Initialize;

   procedure Insert
 (Element : in Element_Type;
  Buffer : in out Buffer_Type)
   is
  End_Index : Element_Index;
  --  Index into the end of the buffer where Element is to be stored.
   begin
  if Element_Index'Last - Buffer.Start_Index = Buffer.Count then
 End_Index := Buffer.Start_Index + Buffer.Count;
  else
 End_Index := Element_Index'First +
  (Buffer.Count - ((Element_Index'Last - Buffer.Start_Index) + 1));
  end if;

  Copy_Element (From_Element = Element,
 To_Element = Buffer.Elements (End_Index));

  Buffer.Count := Buffer.Count + 1;
   end Insert;

   procedure Remove
 (Buffer : in out Buffer_Type;
  Element : out Element_Type)
   is
   begin
  Copy_Element (From_Element = Buffer.Elements (Buffer.Start_Index),
To_Element = Element);

  Discard_First (Buffer);
   end Remove;

   procedure Discard_First (Buffer : in out Buffer_Type) is
   begin
  if Buffer.Start_Index = Element_Index'Last then
 Buffer.Start_Index := Element_Index'First;
  else
 Buffer.Start_Index := Buffer.Start_Index + 1;
  end if;

  Buffer.Count := Buffer.Count - 1;
   end Discard_First;

   function Capacity_Used (Buffer : in Buffer_Type) return Element_Count is
   begin
  return Buffer.Count;
   end Capacity_Used;

end Common.Gen_Circular_Buffer;
---
generic
   type Capacity_Count is range ;
   Capacity : Capacity_Count;

   type Element_Type is limited private;

   with procedure Copy_Element (From_Element : in Element_Type;
   To_Element : out Element_Type);
package Common.Gen_Circular_Buffer
  with Pure
is
   type Buffer_Type is limited private;

   type Element_Count is new Capacity_Count range 0 .. Capacity;

   procedure Initialize (Buffer : out Buffer_Type);

   procedure Insert (Element : in Element_Type; Buffer : in out Buffer_Type)
   with Pre = Capacity_Used (Buffer)  Element_Count'Last;

   procedure Remove (Buffer : in out Buffer_Type; Element : out Element_Type)
   with Pre = Capacity_Used (Buffer)  0;

   procedure Discard_First (Buffer : in out Buffer_Type)
   with Pre = Capacity_Used (Buffer)  0;

   function Capacity_Used (Buffer : in Buffer_Type) return Element_Count;
private

   subtype Element_Index is Element_Count range 1 .. Element_Count'Last;

   type Element_Array is array (Element_Index) of Element_Type;

   type Buffer_Type is
  record
 Start_Index : Element_Index;

 Count : Element_Count;

 Elements : Element_Array;
 --  Element storage.
  end record;
end Common.Gen_Circular_Buffer;
---
package Common
with Pure
is
end Common;

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

2014-10-10  Ed Schonberg  schonb...@adacore.com

* sem_ch13.adb (Analyze_Aspect_Specifications, Library_Unit_Aspects):
Aspect specification is legal on a local instantiation of a
library-level generic unit.

Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 216081)
+++ sem_ch13.adb(working copy)
@@ -3018,12 +3018,15 @@
   --  of a package declaration, the pragma needs to be inserted
   --  in the list of declarations for the associated package.
   --  There is no issue of visibility delay for these aspects.
+  --  Aspect is legal on a local instantiation of a library-
+  --  level generic unit.
 
   if A_Id in Library_Unit_Aspects
 and then
   Nkind_In (N, N_Package_Declaration,
N_Generic_Package_Declaration)
 and then Nkind (Parent (N)) /= N_Compilation_Unit
+and then not Is_Generic_Instance (Defining_Entity (N))
   then
  

[Ada] Ada2012 freeze rules for subprogram profiles

2014-10-10 Thread Arnaud Charlet
Ada05-019 specifies that freezing a subprogram does not automatically freeze
the profile, i.e. the types of the formals and the return type. In particular
an attribute reference 'Access and its relatives do not freeze the profile.

Compiling bd.ads must yield:

   bd.ads:15:34: incorrect expression for READ attribute

---
with Ada.Streams;
package BD is
type My_Big_Int is range 0 .. 1;

type Write_Ptr is access procedure
   (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
A  : in My_Big_Int'Base);

procedure Good_Write6
   (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
A  : in My_Big_Int'Base);

WPtr : Write_Ptr := Good_Write6'Access;
-- Does not freeze My_Big_Int (AI05-0019-1).
for My_Big_Int'Read use WPtr.all;  -- ERROR:

private
type My_Priv (D : Integer) is null record;
end BD;

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

2014-10-10  Ed Schonberg  schonb...@adacore.com

* freeze.adb (Freeze_Entity): Freezing a subprogram does
not always freeze its profile.  In particular, an attribute
reference that takes the access type does not freeze the types
of the formals.

Index: freeze.adb
===
--- freeze.adb  (revision 216089)
+++ freeze.adb  (working copy)
@@ -4004,7 +4004,17 @@
 --  any extra formal parameters are created since we now know
 --  whether the subprogram will use a foreign convention.
 
-if not Is_Internal (E) then
+--  In Ada 2012, freezing a subprogram does not always freeze
+--  the corresponding profile (see AI05-019). An attribute
+--  reference is not a freezing point of the profile.
+--  Other constructs that should not freeze ???
+
+if Ada_Version  Ada_2005
+  and then Nkind (N) = N_Attribute_Reference
+then
+   null;
+
+elsif not Is_Internal (E) then
declare
   F_Type: Entity_Id;
   R_Type: Entity_Id;


[Ada] Missing inheritance of pragma Default_Initial_Condition

2014-10-17 Thread Arnaud Charlet
This patch modifies the inheritance of all attributes related to pragma
Default_Initial_Condition to account for a case where the full view of
a private type derives from another private type.


-- Source --


--  parent.ads

package Parent is
   type Parent_Typ is private
 with Default_Initial_Condition = False;
private
   type Parent_Typ is null record;
end Parent;

--  derivation.ads

with Parent; use Parent;

package Derivation is
   type Derivation_Typ is private;
private
   type Derivation_Typ is new Parent_Typ;
end Derivation;

--  derivation_check.adb

with Ada.Assertions; use Ada.Assertions;
with Ada.Text_IO;use Ada.Text_IO;
with Derivation; use Derivation;

procedure Derivation_Check is
begin
   declare
  Obj : Derivation_Typ;
   begin
  Put_Line (ERROR: Default_Initial_Condition not triggered);
   end;
exception
   when Assertion_Error =
  Put_Line (OK);
   when others  =
  Put_Line (ERROR: expected Assertion_Error);
end Derivation_Check;


-- Compilation and output --


$ gnatmake -q -gnata derivation_check.adb
$ ./derivation_check
OK

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

2014-10-17  Hristian Kirtchev  kirtc...@adacore.com

* sem_ch3.adb (Build_Derived_Record_Type): Remove the propagation
of all attributes related to pragma Default_Initial_Condition.
(Build_Derived_Type): Propagation of all attributes related
to pragma Default_Initial_Condition.
(Process_Full_View): Account for the case where the full view derives
from another private type and propagate the attributes related
to pragma Default_Initial_Condition to the private view.
(Propagate_Default_Init_Cond_Attributes): New routine.
* sem_util.adb: Alphabetize various routines.
(Build_Default_Init_Cond_Call): Use an unchecked type conversion
when calling the default initial condition procedure of a private type.
(Build_Default_Init_Cond_Procedure_Declaration): Prevent
the generation of multiple default initial condition procedures.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 216367)
+++ sem_ch3.adb (working copy)
@@ -650,6 +650,17 @@
--  present. If errors are found, error messages are posted, and the
--  Real_Range_Specification of Def is reset to Empty.
 
+   procedure Propagate_Default_Init_Cond_Attributes
+ (From_Typ : Entity_Id;
+  To_Typ   : Entity_Id;
+  Parent_To_Derivation : Boolean := False;
+  Private_To_Full_View : Boolean := False);
+   --  Subsidiary to routines Build_Derived_Type and Process_Full_View. Inherit
+   --  all attributes related to pragma Default_Initial_Condition from From_Typ
+   --  to To_Typ. Flag Parent_To_Derivation should be set when the context is
+   --  the creation of a derived type. Flag Private_To_Full_View should be set
+   --  when processing both views of a private type.
+
procedure Record_Type_Declaration
  (T: Entity_Id;
   N: Node_Id;
@@ -8546,23 +8557,6 @@
   end if;
 
   Check_Function_Writable_Actuals (N);
-
-  --  Propagate the attributes related to pragma Default_Initial_Condition
-  --  from the parent type to the private extension. A derived type always
-  --  inherits the default initial condition flag from the parent type. If
-  --  the derived type carries its own Default_Initial_Condition pragma,
-  --  the flag is later reset in Analyze_Pragma. Note that both flags are
-  --  mutually exclusive.
-
-  if Has_Inherited_Default_Init_Cond (Parent_Type)
-or else Present (Get_Pragma
-  (Parent_Type, Pragma_Default_Initial_Condition))
-  then
- Set_Has_Inherited_Default_Init_Cond (Derived_Type);
-
-  elsif Has_Default_Init_Cond (Parent_Type) then
- Set_Has_Default_Init_Cond (Derived_Type);
-  end if;
end Build_Derived_Record_Type;
 

@@ -8680,6 +8674,18 @@
  Set_First_Rep_Item (Derived_Type, First_Rep_Item (Parent_Type));
   end if;
 
+  --  Propagate the attributes related to pragma Default_Initial_Condition
+  --  from the parent type to the private extension. A derived type always
+  --  inherits the default initial condition flag from the parent type. If
+  --  the derived type carries its own Default_Initial_Condition pragma,
+  --  the flag is later reset in Analyze_Pragma. Note that both flags are
+  --  mutually exclusive.
+
+  Propagate_Default_Init_Cond_Attributes
+(From_Typ = Parent_Type,
+ To_Typ   = Derived_Type,
+ Parent_To_Derivation = True);
+
   --  If the parent type has delayed rep aspects, then mark the derived
   --  type as possibly inheriting a delayed rep aspect.
 
@@ -10008,6 +10014,401 @@

[Ada] Ensure record type equality treated correctly for codepeer

2014-10-17 Thread Arnaud Charlet
This is an internal change that does not affect the compiler, but fixes
a problem in which a record comparison was not properly expanded. The
compiler back end handled this, but it blew up codepeer. No further
test required.

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

2014-10-17  Robert Dewar  de...@adacore.com

* exp_ch4.adb (Expand_N_Op_Eq): Make sure we deal with the
implementation base type.
* sinfo.ads: Add a note for N_Op_Eq and N_Op_Ne that record
operands are always expanded out into component comparisons.

Index: exp_ch4.adb
===
--- exp_ch4.adb (revision 216367)
+++ exp_ch4.adb (working copy)
@@ -7152,8 +7152,11 @@
  return;
   end if;
 
-  Typl := Base_Type (Typl);
+  --  Now get the implementation base type (note that plain Base_Type here
+  --  might lead us back to the private type, which is not what we want!)
 
+  Typl := Implementation_Base_Type (Typl);
+
   --  Equality between variant records results in a call to a routine
   --  that has conditional tests of the discriminant value(s), and hence
   --  violates the No_Implicit_Conditionals restriction.
Index: sinfo.ads
===
--- sinfo.ads   (revision 216367)
+++ sinfo.ads   (working copy)
@@ -4246,6 +4246,11 @@
   --  point operands if the Treat_Fixed_As_Integer flag is set and will
   --  thus treat these nodes in identical manner, ignoring small values.
 
+  --  Note on equality/inequality tests for records. In the expanded tree,
+  --  record comparisons are always expanded to be a series of component
+  --  comparisons, so the back end will never see an equality or inequality
+  --  operation with operands of a record type.
+
   --  Note on overflow handling: When the overflow checking mode is set to
   --  MINIMIZED or ELIMINATED, nodes for signed arithmetic operations may
   --  be modified to use a larger type for the operands and result. In


[Ada] Make System.Atomic_Counters available to user applications

2014-10-17 Thread Arnaud Charlet
The system unit System.Atomic_Counters which provides an atomic
counter type, along with increment, decrement and test operations,
available to user programs.

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

2014-10-17  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document System.Atomic_Counters.
* impunit.adb: Add System.Atomic_Counters (s-atocou.ads) to the
list of user- accessible units added as children of System.
* s-atocou.ads: Update comment.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 216367)
+++ gnat_rm.texi(working copy)
@@ -661,6 +661,7 @@
 * Interfaces.VxWorks.IO (i-vxwoio.ads)::
 * System.Address_Image (s-addima.ads)::
 * System.Assertions (s-assert.ads)::
+* System.Atomic_Counters (s-atocou.ads)::
 * System.Memory (s-memory.ads)::
 * System.Multiprocessors (s-multip.ads)::
 * System.Multiprocessors.Dispatching_Domains (s-mudido.ads)::
@@ -19074,6 +19075,7 @@
 * Interfaces.VxWorks.IO (i-vxwoio.ads)::
 * System.Address_Image (s-addima.ads)::
 * System.Assertions (s-assert.ads)::
+* System.Atomic_Counters (s-atocou.ads)::
 * System.Memory (s-memory.ads)::
 * System.Multiprocessors (s-multip.ads)::
 * System.Multiprocessors.Dispatching_Domains (s-mudido.ads)::
@@ -20585,6 +20587,18 @@
 by an run-time assertion failure, as well as the routine that
 is used internally to raise this assertion.
 
+@node System.Atomic_Counters (s-atocou.ads)
+@section @code{System.Atomic_Counters} (@file{s-atocou.ads})
+@cindex @code{System.Atomic_Counters} (@file{s-atocou.ads})
+
+@noindent
+This package provides the declaration of an atomic counter type,
+together with efficient routines (using hardware
+synchronization primitives) for incrementing, decrementing,
+and testing of these counters. This package is implemented
+on most targets, including all Alpha, ia64, PowerPC, SPARC V9,
+x86, and x86_64 platforms.
+
 @node System.Memory (s-memory.ads)
 @section @code{System.Memory} (@file{s-memory.ads})
 @cindex @code{System.Memory} (@file{s-memory.ads})
Index: impunit.adb
===
--- impunit.adb (revision 216367)
+++ impunit.adb (working copy)
@@ -367,6 +367,7 @@
--
 
 (s-addima, F),  -- System.Address_Image
+(s-atocou, F),  -- System.Atomic_Counters
 (s-assert, F),  -- System.Assertions
 (s-diflio, F),  -- System.Dim.Float_IO
 (s-diinio, F),  -- System.Dim.Integer_IO
Index: s-atocou.ads
===
--- s-atocou.ads(revision 216367)
+++ s-atocou.ads(working copy)
@@ -6,7 +6,7 @@
 --  --
 -- S p e c  --
 --  --
---  Copyright (C) 2011-2013, Free Software Foundation, Inc. --
+--  Copyright (C) 2011-2014, Free Software Foundation, Inc. --
 --  --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -37,8 +37,6 @@
 --- all x86 platforms
 --- all x86_64 platforms
 
---  Why isn't this package available to application programs???
-
 package System.Atomic_Counters is
 
pragma Preelaborate;
@@ -59,20 +57,19 @@
 
function Decrement (Item : in out Atomic_Counter) return Boolean;
pragma Inline_Always (Decrement);
-   --  Decrements value of atomic counter, returns True when value reach zero.
+   --  Decrements value of atomic counter, returns True when value reach zero
 
function Is_One (Item : Atomic_Counter) return Boolean;
pragma Inline_Always (Is_One);
-   --  Returns True when value of the atomic counter is one.
+   --  Returns True when value of the atomic counter is one
 
procedure Initialize (Item : out Atomic_Counter);
pragma Inline_Always (Initialize);
--  Initialize counter by setting its value to one. This subprogram is
-   --  intended to be used in special cases when counter object can't be
+   --  intended to be used in special cases when the counter object cannot be
--  initialized in standard way.
 
 private
-
type Unsigned_32 is mod 2 ** 32;
 
type Atomic_Counter is limited record


[Ada] String literal is allowed for pragma Warnings in Ada 83

2014-10-17 Thread Arnaud Charlet
Documentation change only, no further test required

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

2014-10-17  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document that string literal can be used for
pragma Warnings when operating in Ada 83 mode.

Index: gnat_rm.texi
===
--- gnat_rm.texi(revision 216371)
+++ gnat_rm.texi(working copy)
@@ -7829,6 +7829,9 @@
 pragma Warnings (On | Off, static_string_EXPRESSION [,REASON]);
 
 REASON ::= Reason = STRING_LITERAL @{ STRING_LITERAL@}
+
+Note: in Ada 83 mode, a string literal may be used in place of
+a static string expression (which does not exist in Ada 83).
 @end smallexample
 
 @noindent


[Ada] Class-wide type invariants for type extensions in other units.

2014-10-17 Thread Arnaud Charlet
A class-wide type invariant is inherited by a type extension, and incorporated
into the invariant procedure for that type. When the expression for such an
invariant (typically a function call) is first analyzed, we must preserve some
semantic information in it, because the type extension may be declared in a
different unit, where it cannot be resolved by visibility if it refers to
local entities.

The following must compile quietly:
   gcc -c -gnata inv2.ads

---
package Inv1 is
   type T_Inv1 is tagged private with
  Type_Invariant'Class = Invariant (T_Inv1);

   function Invariant (This : in T_Inv1'Class) return Boolean;
   type T_Inv2 is new Inv1.T_Inv1 with private;

private
   type T_Inv1 is tagged record
  Value : Integer := 1234;
   end record;

   function Invariant (This : in T_Inv1'Class) return Boolean is
  (This.Value  1000);

   type T_Inv2 is new Inv1.T_Inv1 with null record;
end Inv1;
---
with Inv1;
package Inv2 is
   type T_Inv2 is new Inv1.T_Inv1 with private;
private
   type T_Inv2 is new Inv1.T_Inv1 with null record;
end Inv2;

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

2014-10-17  Ed Schonberg  schonb...@adacore.com

* sem_ch13.adb (Add_Invariants): For a class-wide type invariant,
preserve semantic information on the invariant expression
(typically a function call) because it may be inherited by a
type extension in a different unit, and it cannot be resolved
by visibility elsewhere because it may refer to local entities.

Index: sem_ch13.adb
===
--- sem_ch13.adb(revision 216367)
+++ sem_ch13.adb(working copy)
@@ -2947,8 +2947,7 @@
 --  evaluation of this aspect should be delayed to the
 --  freeze point (why???)
 
-if No (Expr)
-  or else Is_True (Static_Boolean (Expr))
+if No (Expr) or else Is_True (Static_Boolean (Expr))
 then
Set_Uses_Lock_Free (E);
 end if;
@@ -3621,10 +3620,10 @@
if (Attr = Name_Constant_Indexing
 and then Present
   (Find_Aspect (Etype (Ent), Aspect_Constant_Indexing)))
-
- or else (Attr = Name_Variable_Indexing
-and then Present
-  (Find_Aspect (Etype (Ent), Aspect_Variable_Indexing)))
+ or else
+   (Attr = Name_Variable_Indexing
+ and then Present
+   (Find_Aspect (Etype (Ent), Aspect_Variable_Indexing)))
then
   if Debug_Flag_Dot_XX then
  null;
@@ -4269,11 +4268,7 @@
 
 --  Case of address clause for a (non-controlled) object
 
-elsif
-  Ekind (U_Ent) = E_Variable
-or else
-  Ekind (U_Ent) = E_Constant
-then
+elsif Ekind_In (U_Ent, E_Variable, E_Constant) then
declare
   Expr  : constant Node_Id := Expression (N);
   O_Ent : Entity_Id;
@@ -4295,7 +4290,7 @@
 
   if Present (O_Ent)
 and then (Has_Controlled_Component (Etype (O_Ent))
-or else Is_Controlled (Etype (O_Ent)))
+   or else Is_Controlled (Etype (O_Ent)))
   then
  Error_Msg_N
(??cannot overlay with controlled object, Expr);
@@ -4826,13 +4821,10 @@
 --  except from aspect specification.
 
 if From_Aspect_Specification (N) then
-   if not (Is_Protected_Type (U_Ent)
-or else Is_Task_Type (U_Ent))
-   then
+   if not Is_Concurrent_Type (U_Ent) then
   Error_Msg_N
-(Interrupt_Priority can only be defined for task 
- and protected object,
- Nam);
+(Interrupt_Priority can only be defined for task 
+  and protected object, Nam);
 
elsif Duplicate_Clause then
   null;
@@ -4985,14 +4977,12 @@
 --  aspect specification.
 
 if From_Aspect_Specification (N) then
-   if not (Is_Protected_Type (U_Ent)
-or else Is_Task_Type (U_Ent)
+   if not (Is_Concurrent_Type (U_Ent)
 or else Ekind (U_Ent) = E_Procedure)
then
   Error_Msg_N
-(Priority can only be defined for task and protected  
- object,
- Nam);
+(Priority can only be defined for task and protected 
+  object, Nam);
 
elsif Duplicate_Clause then
  

[Ada] Fix obscure case of compiler crash on bad attribute

2014-10-17 Thread Arnaud Charlet
This fixes an error in the handling of attributes where the prefix
raises an exception. This resulted from other errors in the program.
No simple test case has been found, but the correction is clearly
safe.

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

2014-10-17  Robert Dewar  de...@adacore.com

* sem_attr.adb (Eval_Attribute): Ensure that attribute
reference is not marked as being a static expression if the
prefix evaluation raises CE.

Index: sem_attr.adb
===
--- sem_attr.adb(revision 216367)
+++ sem_attr.adb(working copy)
@@ -7553,15 +7553,17 @@
Static :=
  Static and then not Is_Constr_Subt_For_U_Nominal (P_Type);
Set_Is_Static_Expression (N, Static);
-
 end if;
 
 while Present (Nod) loop
if not Is_Static_Subtype (Etype (Nod)) then
   Static := False;
   Set_Is_Static_Expression (N, False);
+
elsif not Is_OK_Static_Subtype (Etype (Nod)) then
   Set_Raises_Constraint_Error (N);
+  Static := False;
+  Set_Is_Static_Expression (N, False);
end if;
 
--  If however the index type is generic, or derived from
@@ -7591,6 +7593,7 @@
 
   begin
  E := E1;
+
  while Present (E) loop
 
 --  If expression is not static, then the attribute reference
@@ -7638,6 +7641,7 @@
  end loop;
 
  if Raises_Constraint_Error (Prefix (N)) then
+Set_Is_Static_Expression (N, False);
 return;
  end if;
   end;


[Ada] Better messages for missing entities in configurable runtime

2014-10-17 Thread Arnaud Charlet
A new mechanism has been implemented that allows specialization of
error messages for missing entities in a configurable run-time.
Instead of just outputting the (sometimes obscure) name of the
entity involved, a more meaningful message can be issued. This
new mechanism is used for a case of rendezvous not being supported
and also for packed array operations not being supported.

Also in the case of unsupported array packing, the message is now
issued explicitly on the array type entity, as shown in this
test program (compiled with -gnatld7 -gnatj55)

 1. pragma No_Run_Time;
 2. procedure BadPack (M : Integer) is
 3.type R is mod 2 ** 43;
 4.type A is array (1 .. 10) of R;
|
 packing of 43-bit components not allowed
in no run time mode

 5.pragma Pack (A);
 6.AV : A;
 7. begin
 8.AV (M) := 3;
  |
 construct not allowed in no run time mode
 packed component size of 43 is not
supported

 9. end;

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

2014-10-17  Robert Dewar  de...@adacore.com

* exp_pakd.adb: Move bit packed entity tables to spec.
* exp_pakd.ads: Move bit packed entity tables here from body.
* freeze.adb (Freeze_Array_Type): Check that packed array type
is supported.
* rtsfind.adb (PRE_Id_Table): New table (Entity_Not_Defined):
Specialize messages using PRE_Id_Table.
* uintp.ads, uintp.adb (UI_Image): New functional form.

Index: exp_pakd.adb
===
--- exp_pakd.adb(revision 216367)
+++ exp_pakd.adb(working copy)
@@ -34,7 +34,6 @@
 with Nlists;   use Nlists;
 with Nmake;use Nmake;
 with Opt;  use Opt;
-with Rtsfind;  use Rtsfind;
 with Sem;  use Sem;
 with Sem_Aux;  use Sem_Aux;
 with Sem_Ch3;  use Sem_Ch3;
@@ -77,365 +76,6 @@
--  right rotate into a left rotate, avoiding the subtract, if the machine
--  architecture provides such an instruction.
 
-   --
-   -- Entity Tables for Packed Access Routines --
-   --
-
-   --  For the cases of component size = 3,5-7,9-15,17-31,33-63 we call library
-   --  routines. This table provides the entity for the proper routine.
-
-   type E_Array is array (Int range 01 .. 63) of RE_Id;
-
-   --  Array of Bits_nn entities. Note that we do not use library routines
-   --  for the 8-bit and 16-bit cases, but we still fill in the table, using
-   --  entries from System.Unsigned, because we also use this table for
-   --  certain special unchecked conversions in the big-endian case.
-
-   Bits_Id : constant E_Array :=
- (01 = RE_Bits_1,
-  02 = RE_Bits_2,
-  03 = RE_Bits_03,
-  04 = RE_Bits_4,
-  05 = RE_Bits_05,
-  06 = RE_Bits_06,
-  07 = RE_Bits_07,
-  08 = RE_Unsigned_8,
-  09 = RE_Bits_09,
-  10 = RE_Bits_10,
-  11 = RE_Bits_11,
-  12 = RE_Bits_12,
-  13 = RE_Bits_13,
-  14 = RE_Bits_14,
-  15 = RE_Bits_15,
-  16 = RE_Unsigned_16,
-  17 = RE_Bits_17,
-  18 = RE_Bits_18,
-  19 = RE_Bits_19,
-  20 = RE_Bits_20,
-  21 = RE_Bits_21,
-  22 = RE_Bits_22,
-  23 = RE_Bits_23,
-  24 = RE_Bits_24,
-  25 = RE_Bits_25,
-  26 = RE_Bits_26,
-  27 = RE_Bits_27,
-  28 = RE_Bits_28,
-  29 = RE_Bits_29,
-  30 = RE_Bits_30,
-  31 = RE_Bits_31,
-  32 = RE_Unsigned_32,
-  33 = RE_Bits_33,
-  34 = RE_Bits_34,
-  35 = RE_Bits_35,
-  36 = RE_Bits_36,
-  37 = RE_Bits_37,
-  38 = RE_Bits_38,
-  39 = RE_Bits_39,
-  40 = RE_Bits_40,
-  41 = RE_Bits_41,
-  42 = RE_Bits_42,
-  43 = RE_Bits_43,
-  44 = RE_Bits_44,
-  45 = RE_Bits_45,
-  46 = RE_Bits_46,
-  47 = RE_Bits_47,
-  48 = RE_Bits_48,
-  49 = RE_Bits_49,
-  50 = RE_Bits_50,
-  51 = RE_Bits_51,
-  52 = RE_Bits_52,
-  53 = RE_Bits_53,
-  54 = RE_Bits_54,
-  55 = RE_Bits_55,
-  56 = RE_Bits_56,
-  57 = RE_Bits_57,
-  58 = RE_Bits_58,
-  59 = RE_Bits_59,
-  60 = RE_Bits_60,
-  61 = RE_Bits_61,
-  62 = RE_Bits_62,
-  63 = RE_Bits_63);
-
-   --  Array of Get routine entities. These are used to obtain an element from
-   --  a packed array. The N'th entry is used to obtain elements from a packed
-   --  array whose component size is N. RE_Null is used as a null entry, for
-   --  the cases where a library routine is not used.
-
-   Get_Id : constant E_Array :=
- (01 = RE_Null,
-  02 = RE_Null,
-  03 = RE_Get_03,
-  04 = RE_Null,
-  05 = RE_Get_05,
-  06 = RE_Get_06,
-  07 = RE_Get_07,
-  08 = RE_Null,
-  09 = RE_Get_09,
-  10 = RE_Get_10,
-  11 = RE_Get_11,
-  12 = RE_Get_12,
-  13 = RE_Get_13,
-  14 = RE_Get_14,
-  15 = RE_Get_15,
-  16 = RE_Null,
-  

[Ada] Short_Integer should be considered implementation defined

2014-10-17 Thread Arnaud Charlet
For the purposes of restriction No_Implementation_Identifiers,
Standard.Short_Integer should be considered as being implementation
defined and this was not the case. In addition, this patch fixes
a compiler blow up with a compiler built with assertions in the
test for implementation-defined identifiers. Note that the latter
problem is not documented in the KP entry for this ticket, since
it shows up only in compilers built with assertions.

The following should compile as indicated with -gnatld7 -gnatj55

 1. pragma Restriction_Warnings
 2.  (No_Implementation_Identifiers);
 3. package ImplIdent is
 4.  subtype Integer_8 is Standard.Short_Short_Integer;
   |
 warning: violation of restriction
No_Implementation_Identifiers at line 1

 5.  subtype Integer_16 is Standard.Short_Integer;
|
 warning: violation of restriction
No_Implementation_Identifiers at line 1

 6. end;

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

2014-10-17  Robert Dewar  de...@adacore.com

* cstand.adb (Create_Standard): Mark Short_Integer as
implementation defined.
* sem_util.adb (Set_Entity_With_Checks): Avoid blow up for
compiler built with assertions for No_Implementation_Identifiers test.

Index: sem_util.adb
===
--- sem_util.adb(revision 216371)
+++ sem_util.adb(working copy)
@@ -16462,8 +16462,9 @@
  --  the entities within it).
 
  if (Is_Implementation_Defined (Val)
-   or else
- Is_Implementation_Defined (Scope (Val)))
+  or else
+(Present (Scope (Val))
+  and then Is_Implementation_Defined (Scope (Val
and then not (Ekind_In (Val, E_Package, E_Generic_Package)
   and then Is_Library_Level_Entity (Val))
  then
Index: cstand.adb
===
--- cstand.adb  (revision 216367)
+++ cstand.adb  (working copy)
@@ -735,6 +735,7 @@
 
   Build_Signed_Integer_Type
 (Standard_Short_Integer, Standard_Short_Integer_Size);
+  Set_Is_Implementation_Defined (Standard_Short_Integer);
 
   Build_Signed_Integer_Type
 (Standard_Integer, Standard_Integer_Size);


[Ada] Better error message for illegal iterator expression

2014-10-17 Thread Arnaud Charlet
This patch improves the error message on an iterator specification whose name
is a function call that does not yield a type that implements an iterator
interface.

Compiling try_containers.adb must yield:

   try_containers.adb:17:18: expect object that implements iterator interface

--
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Containers.Vectors;
procedure Try_Containers
is
   package Integer_Vectors is new Ada.Containers.Vectors (Natural, Integer);
   use Integer_Vectors;

   A : Vector := To_Vector (1, 10);
begin
   Loop_1 :
   for Element of A loop
  Put_Line (A (i) =   Integer'Image (Element));
  -- can't do Element := 2;
   end loop Loop_1;

   Loop_2 :
   for Cursor in First (A) loop -- oops! should be:
   --  for Cursor in Iterate (A) loop

  Put_Line (A (I) =   Integer'Image (Element (Cursor)));
  Replace_Element (A, Cursor, 2);
  Reference (A, Cursor) := 2;
   end loop Loop_2;

end Try_Containers;

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

2014-10-17  Ed Schonberg  schonb...@adacore.com

* sem_ch5.adb (Analyze_Iterator_Specification): If the domain
of iteration is given by an expression that is not an array type,
verify that its type implements an iterator iterface.

Index: sem_ch5.adb
===
--- sem_ch5.adb (revision 216367)
+++ sem_ch5.adb (working copy)
@@ -1838,6 +1838,17 @@
 
 else
Typ := Etype (Iter_Name);
+
+   --  Verify that the expression produces an iterator.
+
+   if not Of_Present (N) and then not Is_Iterator (Typ)
+ and then not Is_Array_Type (Typ)
+ and then No (Find_Aspect (Typ, Aspect_Iterable))
+   then
+  Error_Msg_N
+(expect object that implements iterator interface,
+Iter_Name);
+   end if;
 end if;
 
 --  Protect against malformed iterator


[Ada] Directories are no longer created for abstract projects

2014-10-17 Thread Arnaud Charlet
Directories such as object directories are no longer created for abstract
projects when the builder (gnatmake or gprbuild) is called with -P or
with --subdirs=..., even when there is no explicit indication in the
abstract project that there are no sources in the project.

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

2014-10-17  Vincent Celier  cel...@adacore.com

* prj-nmsc.adb (Get_Directories): Do not create directories
when a project is abstract.

Index: prj-nmsc.adb
===
--- prj-nmsc.adb(revision 216367)
+++ prj-nmsc.adb(working copy)
@@ -5498,13 +5498,15 @@
   Dir_Exists : Boolean;
 
   No_Sources : constant Boolean :=
- ((not Source_Files.Default
+ Project.Qualifier = Abstract_Project
+   or else
+ (((not Source_Files.Default
 and then Source_Files.Values = Nil_String)
or else (not Source_Dirs.Default
  and then Source_Dirs.Values = Nil_String)
or else (not Languages.Default
  and then Languages.Values = Nil_String))
- and then Project.Extends = No_Project;
+ and then Project.Extends = No_Project);
 
--  Start of processing for Get_Directories
 


[Ada] Internal clean up (use Is_Directory_Separator)

2014-10-17 Thread Arnaud Charlet
This is an internal clean up to use an existing abstraction
more extensively. No external effect, no test required.

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

2014-10-17  Robert Dewar  de...@adacore.com

* gnatcmd.adb, make.adb, prj-part.adb, gnatlink.adb, prj-nmsc.adb,
prj-conf.adb, prj-env.adb: Use Is_Directory_Separator where possible.

Index: gnatcmd.adb
===
--- gnatcmd.adb (revision 216367)
+++ gnatcmd.adb (working copy)
@@ -883,10 +883,9 @@
   if not Is_Absolute_Path (Exec_File_Name) then
  for Index in Exec_File_Name'Range loop
 if Exec_File_Name (Index) = Directory_Separator then
-   Fail (relative executable ( 
-   Exec_File_Name 
-   ) with directory part not allowed  
-   when using project files);
+   Fail (relative executable (  Exec_File_Name
+  ) with directory part not allowed 
+  when using project files);
 end if;
  end loop;
 
@@ -1398,9 +1397,7 @@
 
   else
  for K in Switch'Range loop
-if Switch (K) = '/'
-  or else Switch (K) = Directory_Separator
-then
+if Is_Directory_Separator (Switch (K)) then
Test_Existence := True;
exit;
 end if;
Index: make.adb
===
--- make.adb(revision 216367)
+++ make.adb(working copy)
@@ -4057,8 +4057,7 @@
begin
   First := Name'Last;
   while First  Name'First
-and then Name (First - 1) /= Directory_Separator
-and then Name (First - 1) /= '/'
+and then not Is_Directory_Separator (Name (First - 1))
   loop
  First := First - 1;
   end loop;
@@ -6805,8 +6804,7 @@
  begin
 First := Name'Last;
 while First  Name'First
-  and then Name (First - 1) /= Directory_Separator
-  and then Name (First - 1) /= '/'
+  and then not Is_Directory_Separator (Name (First - 1))
 loop
First := First - 1;
 end loop;
Index: prj-part.adb
===
--- prj-part.adb(revision 216367)
+++ prj-part.adb(working copy)
@@ -349,8 +349,7 @@
   Get_Name_String (Path_Name_Of (Main_Project, In_Tree));
 
   while Name_Len  0
-and then Name_Buffer (Name_Len) /= Directory_Separator
-and then Name_Buffer (Name_Len) /= '/'
+and then not Is_Directory_Separator (Name_Buffer (Name_Len))
   loop
  Name_Len := Name_Len - 1;
   end loop;
Index: gnatlink.adb
===
--- gnatlink.adb(revision 216367)
+++ gnatlink.adb(working copy)
@@ -1204,9 +1204,8 @@
if GCC_Index = 0 then
   GCC_Index :=
 Index (Path (1 .. Path_Last),
-   Directory_Separator 
-   lib 
-   Directory_Separator);
+   Directory_Separator  lib
+Directory_Separator);
end if;
 
--  If we have found a lib subdir in
Index: prj-nmsc.adb
===
--- prj-nmsc.adb(revision 216381)
+++ prj-nmsc.adb(working copy)
@@ -5031,10 +5031,7 @@
 
if OK then
   for J in 1 .. Name_Len loop
- if Name_Buffer (J) = '/'
-  or else
-Name_Buffer (J) = Directory_Separator
- then
+ if Is_Directory_Separator (Name_Buffer (J)) then
 OK := False;
 exit;
  end if;
@@ -5336,9 +5333,7 @@
function Compute_Directory_Last (Dir : String) return Natural is
begin
   if Dir'Length  1
-and then (Dir (Dir'Last - 1) = Directory_Separator
-or else
-  Dir (Dir'Last - 1) = '/')
+and then Is_Directory_Separator (Dir (Dir'Last - 1))
   then
  return Dir'Last - 1;
   else
@@ -5858,7 +5853,7 @@
--  Check that there is no directory information
 
for J in 1 .. Last loop
-  if Line (J) = '/' or else Line (J) = Directory_Separator then
+  if 

[Ada] Spurious output on optimized default-initialized limited aggregate

2014-10-20 Thread Arnaud Charlet
When expanding a limited aggregate into individual assignments, we create a
transient scope if the type of a component requires it. This must not be done
if the context is an initialization procedure, because the target of the
assignment must be visible outside of the block, and stack cleanup will happen
on return from the initialization call. Otherwise this may result in dangling
stack references in the back-end, which produce garbled results when compiled
at higher optimization levels.

Executing the following:

   gnatmake -q -O2 cutdown
   cutdown

must yield:

   0.0E+00

---
with Text_IO; use Text_IO;
procedure Cutdown is

   type Angle_Object_T is tagged record
  M_Value : Float := 0.0;
   end record;

   Zero : constant Angle_Object_T := (M_Value = 0.0);

   type Platform_T is record
  M_Roll : Angle_Object_T := Zero;
   end record;

   package Observable_Nongeneric is
  type Writer_T is tagged limited record
 M_Value : Platform_T;
  end record;

  function Init (Value : in Platform_T) return Writer_T;
   end Observable_Nongeneric;

   package body Observable_Nongeneric is

   --
  function Init (Value : in Platform_T) return Writer_T is
  begin
 return (M_Value = Value);
  end Init;
   --
   end Observable_Nongeneric;

   type Object_T is tagged limited record
  M_Platform : aliased Observable_Nongeneric.Writer_T :=
Observable_Nongeneric.Init (Platform_T'(others = ));
   end record;

   Data : Object_T;
begin
   Put_Line (Data.M_Platform.M_Value.M_Roll.M_Value'Img);

   if Data.M_Platform.M_Value.M_Roll.M_Value /= 0.0 then
  raise Program_Error;
   end if;
end Cutdown;

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

2014-10-20  Ed Schonberg  schonb...@adacore.com

* exp_aggr.adb (Convert_To_Assignments): Do not create a
transient scope for a component whose type requires it, if the
context is an initialization procedure, because the target of
the assignment must be visible outside of the block.

Index: exp_aggr.adb
===
--- exp_aggr.adb(revision 216469)
+++ exp_aggr.adb(working copy)
@@ -3396,7 +3396,7 @@
  --  that any finalization chain will be associated with that scope.
  --  For extended returns, we delay expansion to avoid the creation
  --  of an unwanted transient scope that could result in premature
- --  finalization of the return object (which is built in in place
+ --  finalization of the return object (which is built in place
  --  within the caller's scope).
 
  or else
@@ -3409,7 +3409,14 @@
  return;
   end if;
 
-  if Requires_Transient_Scope (Typ) then
+  --  Otherwise, if a transient scope is required, create it now. If we
+  --  are within an initialization procedure do not create such, because
+  --  the target of the assignment must not be declared within a local
+  --  block, and because cleanup will take place on return from the
+  --  initialization procedure.
+  --  Should the condition be more restrictive ???
+
+  if Requires_Transient_Scope (Typ) and then not Inside_Init_Proc then
  Establish_Transient_Scope (N, Sec_Stack = Needs_Finalization (Typ));
   end if;
 


[Ada] Aspect specifications and incomplete views

2014-10-20 Thread Arnaud Charlet
Typically an indexing aspect is specified on the private view of a tagged
type. In the unusual case where there is an incomplete view and the aspect
specification appears on the full view, the aspect specification must be
analyzed on the full view rather than the incomplete one, to prevent freezing
anomalies with the class-wide type, which otherwise might be frozen before
the dispatch table for the type is constructed.

Compiling and executing try2.adb must yield:

   ab

---
pragma Ada_2012;
with Ada.Text_IO; use Ada.Text_IO;
procedure Try2 is
   package Pack is
  type T is tagged;
  function F (Obj : T; S : String; Pos : Positive) return Character;
  type T is tagged null record
with Constant_Indexing = F;
   end Pack;

   package body Pack is
  function F (Obj : T; S : String; Pos : Positive) return Character is
  begin
 return S (Pos);
  end F;
   end Pack;
   use Pack;

   V : T;
begin
   Put (V (abcd, 1));
   Put (V (abcd, 2));
   New_Line;
end Try2;

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

2014-10-20  Ed Schonberg  schonb...@adacore.com

* sem_ch3.adb (Analyze_Full_Type_Declaration): If previous view
is incomplete rather than private, and full type declaration
has aspects, analyze aspects on the full view rather than
the incomplete view, to prevent freezing anomalies with the
class-wide type.

Index: sem_ch3.adb
===
--- sem_ch3.adb (revision 216469)
+++ sem_ch3.adb (working copy)
@@ -2777,9 +2777,18 @@
   --  them to the entity for the type which is currently the partial
   --  view, but which is the one that will be frozen.
 
+  --  In most cases the partial view is a private type, and both views
+  --  appear in different declarative parts. In the unusual case where the
+  --  partial view is incomplete, perform the analysis on the full view,
+  --  to prevent freezing anomalies with the corresponding class-wide type,
+  --  which otherwise might be frozen before the dispatch table is built.
+
   if Has_Aspects (N) then
- if Prev /= Def_Id then
+ if Prev /= Def_Id
+   and then Ekind (Prev) /= E_Incomplete_Type
+ then
 Analyze_Aspect_Specifications (N, Prev);
+
  else
 Analyze_Aspect_Specifications (N, Def_Id);
  end if;


[Ada] Lift limitation on inter-unit inlining of instantiated subprograms

2014-10-20 Thread Arnaud Charlet
This change makes it so that instantiations of generic subprograms marked as
inline are considered for inter-unit inlining.  This was not previously the
case because of a technical limitation that was too broadly enforced (unlike
the associated comment which was more accurate) and excluded instantiations.

The call to Q.Compare must be inlined if the code is compiled with -O -gnatn:

with Q;

function F (A, B : Integer) return Boolean is
begin
  return Q.Compare (A, B);
end;
with G;

package Q is

  function Compare is new G (Integer);

end Q;
generic
  type T is ();
function G (Left,Right : T) return Boolean;
pragma Inline (G);
function G (Left,Right : T) return Boolean is
begin
  return Left /= Right;
end;

2014-10-20  Eric Botcazou  ebotca...@adacore.com

* inline.adb (List_Inlining_Info): Minor tweaks.
(Add_Inlined_Body): Inline the enclosing package
if it is not internally generated, even if it doesn't come
from source.

Index: inline.adb
===
--- inline.adb  (revision 216469)
+++ inline.adb  (working copy)
@@ -414,7 +414,7 @@
 
elsif Level = Inline_Package
  and then not Is_Inlined (Pack)
- and then Comes_From_Source (E)
+ and then not Is_Internal (E)
  and then not In_Main_Unit_Or_Subunit (Pack)
then
   Set_Is_Inlined (Pack);
@@ -3888,7 +3888,7 @@
Count := Count + 1;
 
if Count = 1 then
-  Write_Str (Listing of frontend inlined calls);
+  Write_Str (List of calls inlined by the frontend);
   Write_Eol;
end if;
 
@@ -3917,7 +3917,7 @@
Count := Count + 1;
 
if Count = 1 then
-  Write_Str (Listing of inlined calls passed to the backend);
+  Write_Str (List of inlined calls passed to the backend);
   Write_Eol;
end if;
 
@@ -3947,7 +3947,7 @@
 
 if Count = 1 then
Write_Str
- (Listing of inlined subprograms passed to the backend);
+ (List of inlined subprograms passed to the backend);
Write_Eol;
 end if;
 
@@ -3964,7 +3964,7 @@
  end loop;
   end if;
 
-  --  Generate listing of subprogram that cannot be inlined by the backend
+  --  Generate listing of subprograms that cannot be inlined by the backend
 
   if Present (Backend_Not_Inlined_Subps)
 and then Back_End_Inlining
@@ -3979,7 +3979,7 @@
 
 if Count = 1 then
Write_Str
- (Listing of subprograms that cannot inline the backend);
+ (List of subprograms that cannot be inlined by the backend);
Write_Eol;
 end if;
 


[Ada] Implement pragma/aspect No_Tagged_Streams

2014-10-20 Thread Arnaud Charlet
The No_Tagged_Streams pragma (and aspect) provides a method for
selectively inhibiting the generation of stream routines for
tagged types. It can be used either in a form naming a specific
tagged type, or in a sequence of declarations to apply to all
subsequent declarations.

The following tests show the use of the pragma and the rejection
of attempts to use stream operations on affected types.

 1. with Ada.Text_IO; use Ada.Text_IO;
 2. with Ada.Text_IO.Text_Streams;
 3. use  Ada.Text_IO.Text_Streams;
 4. procedure NTS1 is
 5.f : File_Type;
 6.type R is tagged null record;
 7.pragma No_Tagged_Streams (R);
 8.RV : R;
 9. begin
10.R'Write (Stream (f), RV);
|
 no stream operations for R
(No_Tagged_Streams at line 7)

11. end;

 1. with Ada.Text_IO; use Ada.Text_IO;
 2. with Ada.Text_IO.Text_Streams;
 3. use  Ada.Text_IO.Text_Streams;
 4. procedure NTS2 is
 5.pragma No_Tagged_Streams;
 6.f : File_Type;
 7.type R is tagged null record;
 8.RV : R;
 9. begin
10.R'Write (Stream (f), RV);
|
 no stream operations for R
(No_Tagged_Streams at line 5)

11. end;

 1. with Ada.Text_IO; use Ada.Text_IO;
 2. with Ada.Text_IO.Text_Streams;
 3. use  Ada.Text_IO.Text_Streams;
 4. procedure NTS3 is
 5.f : File_Type;
 6.pragma No_Tagged_Streams;
 7.type R is tagged null record;
 8.RV : R;
 9. begin
10.R'Write (Stream (f), RV);
|
 no stream operations for R
(No_Tagged_Streams at line 6)

11. end;

 1. package NTS4 is
 2.pragma No_Tagged_Streams;
 3.type R is tagged null record;
 4. end;

 1. with Ada.Text_IO; use Ada.Text_IO;
 2. with Ada.Text_IO.Text_Streams;
 3. use  Ada.Text_IO.Text_Streams;
 4. with NTS4; use NTS4;
 5. procedure NTS4M is
 6.f : File_Type;
 7.RV : R;
 8. begin
 9.R'Write (Stream (f), RV);
|
 no stream operations for R
(No_Tagged_Streams at nts4.ads:2)

10. end;

 1. with Ada.Text_IO; use Ada.Text_IO;
 2. with Ada.Text_IO.Text_Streams;
 3. use  Ada.Text_IO.Text_Streams;
 4. procedure NTS5 is
 5.f : File_Type;
 6.type R is tagged null record
 7.  with No_Tagged_Streams = True;
 8.type R1 is new R with
 9.   record F : Integer; end record;
10.RV : R1;
11. begin
12.R1'Write (Stream (f), RV);
 |
 no stream operations for R1
(No_Tagged_Streams at line 7)

13. end;

The following test shows the rejection of incorrect usage

 1. pragma No_Tagged_Streams;
|
 pragma NO_TAGGED_STREAMS is not in
declarative part or package spec

 2. procedure NTS6 is
 3.type R is new Integer;
 4.pragma No_Tagged_Streams (Entity = R);
   |
 argument for pragma NO_TAGGED_STREAMS
must be root tagged type

 5. begin
 6.null;
 7. end;

2014-10-20  Robert Dewar  de...@adacore.com

* gnat_rm.texi: Document No_Tagged_Streams pragma and aspect.
* snames.ads-tmpl: Add entry for pragma No_Tagged_Streams.
* aspects.ads, aspects.adb: Add aspect No_Tagged_Streams.
* einfo.adb (No_Tagged_Streams_Pragma): New field.
* einfo.ads: Minor reformatting (reorder entries).
(No_Tagged_Streams_Pragma): New field.
* exp_ch3.adb: Minor comment update.
* opt.ads (No_Tagged_Streams): New variable.
* par-prag.adb: Add dummy entry for pragma No_Tagged_Streams.
* sem.ads (Save_No_Tagged_Streams): New field in scope record.
* sem_attr.adb (Check_Stream_Attribute): Check stream ops
prohibited by No_Tagged_Streams.
* sem_ch3.adb (Analyze_Full_Type_Declaration): Set
No_Tagged_Streams_Pragma.
(Analyze_Subtype_Declaration): ditto.
(Build_Derived_Record_Type): ditto.
(Record_Type_Declaration): ditto.
* sem_ch8.adb (Pop_Scope): Restore No_Tagged_Streams.
(Push_Scope): Save No_Tagged_Streams.
* sem_prag.adb (Analyze_Pragma, case No_Tagged_Streams): Implement new
pragma.

Index: aspects.adb
===
--- aspects.adb (revision 216469)
+++ aspects.adb (working copy)
@@ -546,6 +546,7 @@
 Aspect_Machine_Radix= Aspect_Machine_Radix,
 Aspect_No_Elaboration_Code_All  = Aspect_No_Elaboration_Code_All,
 Aspect_No_Return= Aspect_No_Return,
+Aspect_No_Tagged_Streams= Aspect_No_Tagged_Streams,
 Aspect_Obsolescent  = Aspect_Obsolescent,
 Aspect_Object_Size  = Aspect_Object_Size,
 Aspect_Output   = 

[Ada] Improve error recovery for bad comma/semicolon in expression

2014-10-20 Thread Arnaud Charlet
This patch improves the error recovery for an errant comma or semicolon
after one condition in an expression when more conditions follow, as
shown in this example:

 1. procedure BadANDTHEN (X : Integer) is
 2. begin
 3.if X  10
 4.  and then X mod 4 = 2;
 |
 extra ; ignored

 5.  and then X mod 12 = 8
 6.then
 7.   null;
 8.end if;
 9. end;

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

2014-10-20  Robert Dewar  de...@adacore.com

* par-ch4.adb (P_Expression): Handle extraneous comma/semicolon
in middle of expression with logical operators.

Index: par-ch4.adb
===
--- par-ch4.adb (revision 216469)
+++ par-ch4.adb (working copy)
@@ -1708,6 +1708,48 @@
 Node1 := New_Op_Node (Logical_Op, Op_Location);
 Set_Left_Opnd (Node1, Node2);
 Set_Right_Opnd (Node1, P_Relation);
+
+--  Check for case of errant comma or semicolon
+
+if Token = Tok_Comma or else Token = Tok_Semicolon then
+   declare
+  Com: constant Boolean := Token = Tok_Comma;
+  Scan_State : Saved_Scan_State;
+  Logop  : Node_Kind;
+
+   begin
+  Save_Scan_State (Scan_State); -- at comma/semicolon
+  Scan; -- past comma/semicolon
+
+  --  Check for AND THEN or OR ELSE after comma/semicolon. We
+  --  do not deal with AND/OR because those cases get mixed up
+  --  with the select alternatives case.
+
+  if Token = Tok_And or else Token = Tok_Or then
+ Logop := P_Logical_Operator;
+ Restore_Scan_State (Scan_State); -- to comma/semicolon
+
+ if Nkind_In (Logop, N_And_Then, N_Or_Else) then
+Scan; -- past comma/semicolon
+
+if Com then
+   Error_Msg_SP -- CODEFIX
+ (|extra , ignored);
+else
+   Error_Msg_SP -- CODEFIX
+ (|extra ; ignored);
+end if;
+
+ else
+Restore_Scan_State (Scan_State); -- to comma/semicolon
+ end if;
+
+  else
+ Restore_Scan_State (Scan_State); -- to comma/semicolon
+  end if;
+   end;
+end if;
+
 exit when Token not in Token_Class_Logop;
  end loop;
 


[Ada] Improve recognition of misspelled aspects

2014-10-20 Thread Arnaud Charlet
As shown by this example, the recognition of misspelled aspects is
improved:

 1. package UnrecogAs with Prelaborate is
   |
 Prelaborate is not a valid aspect identifier
 possible misspelling of Preelaborate

 2.type R is tagged null record;
 3. end;

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

2014-10-20  Robert Dewar  de...@adacore.com

* par-ch13.adb (Possible_Misspelled_Aspect): New function.


Index: par-ch13.adb
===
--- par-ch13.adb(revision 216469)
+++ par-ch13.adb(working copy)
@@ -45,6 +45,26 @@
   Scan_State : Saved_Scan_State;
   Result : Boolean;
 
+  function Possible_Misspelled_Aspect return Boolean;
+  --  Returns True, if Token_Name is a misspelling of some aspect name
+
+  
+  -- Possible_Misspelled_Aspect --
+  
+
+  function Possible_Misspelled_Aspect return Boolean is
+  begin
+ for J in Aspect_Id_Exclude_No_Aspect loop
+if Is_Bad_Spelling_Of (Token_Name, Aspect_Names (J)) then
+   return True;
+end if;
+ end loop;
+
+ return False;
+  end Possible_Misspelled_Aspect;
+
+   --  Start of processing for Aspect_Specifications_Present
+
begin
   --  Definitely must have WITH to consider aspect specs to be present
 
@@ -74,17 +94,20 @@
   if Token /= Tok_Identifier then
  Result := False;
 
-  --  This is where we pay attention to the Strict mode. Normally when we
-  --  are in Ada 2012 mode, Strict is False, and we consider that we have
-  --  an aspect specification if the identifier is an aspect name (even if
-  --  not followed by =) or the identifier is not an aspect name but is
-  --  followed by =, by a comma, or by a semicolon. The last two cases
-  --  correspond to (misspelled) Boolean aspects with a defaulted value of
-  --  True. P_Aspect_Specifications will generate messages if the aspect
+  --  This is where we pay attention to the Strict mode. Normally when
+  --  we are in Ada 2012 mode, Strict is False, and we consider that we
+  --  have an aspect specification if the identifier is an aspect name
+  --  or a likely misspelling of one (even if not followed by =) or
+  --  the identifier is not an aspect name but is followed by =, by
+  --  a comma, or by a semicolon. The last two cases correspond to
+  --  (misspelled) Boolean aspects with a defaulted value of True.
+  --  P_Aspect_Specifications will generate messages if the aspect
   --  specification is ill-formed.
 
   elsif not Strict then
- if Get_Aspect_Id (Token_Name) /= No_Aspect then
+ if Get_Aspect_Id (Token_Name) /= No_Aspect
+   or else Possible_Misspelled_Aspect
+ then
 Result := True;
  else
 Scan; -- past identifier


  1   2   3   4   5   6   7   8   9   10   >