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


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

[Ada] Aspect Refined_Depends


This patch provides the initial implementation of aspect Refined_Depends along
with its pragma equivalent. This construct is intended for formal verification
purposes.

The syntax of the aspect/pragma is as follows:

   pragma Refined_Depends (DEPENDENCY_RELATION);

   DEPENDENCY_RELATION ::=
     null
     | DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE}

   DEPENDENCY_CLAUSE ::=
     OUTPUT_LIST =>[+] INPUT_LIST
     | NULL_DEPENDENCY_CLAUSE

   NULL_DEPENDENCY_CLAUSE ::= null => INPUT_LIST

   OUTPUT_LIST ::= OUTPUT | (OUTPUT {, OUTPUT})

   INPUT_LIST ::= null | INPUT | (INPUT {, INPUT})

   OUTPUT ::= name | FUNCTION_RESULT
   INPUT  ::= name

   where FUNCTION_RESULT is a function Result attribute_reference

The semantics of the aspect/pragma are as follows:

The static semantics are equivalent to those given for the Depends aspect in
Depends Aspect.

A Refined_Depends aspect shall be specified on a body_stub (if one is present)
or subprogram body if and only if it has a declaration in the visible part of
an enclosing package and the declaration has a Depends aspect which denotes a
state abstraction declared by the package and the refinement of the state
abstraction is visible.

A Refined_Depends aspect specification is, in effect, a copy of the
corresponding Depends aspect specification except that any references in the
Depends aspect to a state abstraction, whose refinement is visible at the point
of the Refined_Depends specification, are replaced with references to zero or
more direct or indirect constituents of that state abstraction. A
Refined_Depends aspect is defined by creating a new dependency_relation from
the original given in the Depends aspect as follows:

  A partially refined dependency relation is created by first copying, from the
Depends aspect, each output that is not state abstraction whose refinement is
visible at the point of the Refined_Depends aspect, along with its input_list,
to the partially refined dependency relation as an output denoting the same
entity with an input_list denoting the same entities as the original.
[The order of the outputs and the order of inputs within the input_list is
insignificant.]

  The partially refined dependency relation is then extended by replacing each
output in the Depends aspect that is a state abstraction, whose refinement is
visible at the point of the Refined_Depends, by zero or more outputs in the
partially refined dependency relation. It shall be zero only for a null
refinement, otherwise all of the outputs shall denote a constituent of the
state abstraction.

  If the output in the Depends_Aspect denotes a state abstraction which is not
also an input, then all of the constituents [for a non-null refinement] of the
state abstraction shall be denoted as outputs of the partially refined
dependency relation.

  These rules may, for each output in the Depends aspect, introduce more than
one output in the partially refined dependency relation. Each of these outputs
has an input_list that has zero or more of the inputs from the input_list of
the original output. The union of these inputs shall denote the same inputs
that appear in the input_list of the original output.

  If the Depends aspect has a null_dependency_clause, then the partially
refined dependency relation has a null_dependency_clause added with an
input_list denoting the same inputs as the original.

  The partially refined dependency relation is completed by replacing the
inputs which are state abstractions, whose refinements are visible at the point
of the Refined_Depends aspect, by zero or more inputs. It shall be zero only
for a null refinement, otherwise each of the inputs shall denote a constituent
of the state abstraction. The completed dependency relation is the
dependency_relation of the Refined_Depends aspect.

These rules result in omitting each state abstraction whose null refinement is
visible at the point of the Refined_Depends. If and only if required by the
syntax, the state abstraction shall be replaced by a null symbol rather than
being omitted.

No other outputs or inputs shall be included in the Refined_Depends aspect
specification. Outputs in the Refined_Depends aspect specification shall denote
distinct entities. Inputs in an input_list shall denote distinct entities.

[The above rules may be viewed from the perspective of checking the consistency
of a Refined_Depends aspect with its corresponding Depends aspect. In this
view, each input in the Refined_Depends aspect that is a constituent of a state
abstraction, whose refinement is visible at the point of the Refined_Depends
aspect, is replaced by its representative state abstraction with duplicate
inputs removed.

Each output in the Refined_Depends aspect, which is a constituent of the same
state abstraction whose refinement is visible at the point of the
Refined_Depends aspect, is merged along with its input_list into a single
dependency_clause whose output denotes the state abstraction and input_list is
the union of all of the inputs from the original input_lists.]

The rules for Depends Aspect also apply.

------------
-- Source --
------------

--  semantics.ads

package Semantics
  with Abstract_State =>
         ((State_1 with External, Input_Only),
           State_2,
          (State_3 with External, Output_Only))
is
   In_Var     : Integer;
   In_Out_Var : Integer;
   Out_Var    : Integer;

   procedure OK_1
     (Formal_1 : in     Integer;
      Formal_2 : in out Integer;
      Formal_3 : out    Integer)
   --  Input  set : Formal_1, Formal_2, In_Var, In_Out_Var,  State_1, State_2
   --  Output set : Formal_2, Formal_3, In_Out_Var, Out_Var, State_2, State_3
   with Global =>
          (Input  => (State_1, In_Var),
           In_Out => (State_2, In_Out_Var),
           Output => (State_3, Out_Var)),
        Depends =>
          ((Formal_2, In_Out_Var, State_2) => (Formal_1, In_Var, State_1),
           (Formal_3, Out_Var, State_3) => (Formal_2, In_Out_Var, State_2));

   procedure OK_2
     (Formal_1 : in     Integer;
      Formal_2 : in out Integer;
      Formal_3 : out    Integer)
   --  Input  set : Formal_1, Formal_2, In_Var, In_Out_Var
   --  Output set : Formal_2, Formal_3, In_Out_Var, Out_Var
   with Global =>
          (Input  => In_Var,
           In_Out => In_Out_Var,
           Output => Out_Var),
        Depends =>
          ((Formal_2, Formal_3, In_Out_Var) => Formal_1,
            Out_Var => (Formal_2, In_Var, In_Out_Var));

private
   Var_2 : Integer;

   package In_Private_Part
     with Abstract_State => (State_7 with Part_Of => State_1)
   is
      Var_3 : Integer;
   private
      Var_4 : Integer;
   end In_Private_Part;
end Semantics;

--  semantics.adb

package body Semantics
  with Refined_State =>
         (State_1 => (Var_2, In_Private_Part.State_7),
          State_2 => (In_Private_Part.Var_3, In_Body.State_8),
          State_3 => (In_Body.Var_6, Var_8))
is
   procedure OK_1
     (Formal_1 : in     Integer;
      Formal_2 : in out Integer;
      Formal_3 : out    Integer)
   --  Input set:
   --    Formal_1
   --    Formal_2
   --    In_Var
   --    In_Out_Var
   --    Var_2 ---------------------+-- State_1
   --    In_Private_Part.State_7 --/
   --    In_Private_Part.Var_3 -----+-- State_2
   --    In_Body.State_8 ----------/

   --  Output set:
   --    Formal_2
   --    Formal_3
   --    In_Out_Var
   --    Out_Var
   --    In_Private_Part.Var_3 -----+-- State_2
   --    In_Body.State_8 ----------/
   --    In_Body.Var_6 -------------+-- State_3
   --    Var_8 --------------------/

   with Refined_Global =>
          (Input  => (Var_2, In_Private_Part.State_7, In_Var),
           In_Out => (In_Private_Part.Var_3, In_Body.State_8, In_Out_Var),
           Output => (In_Body.Var_6, Var_8, Out_Var)),
        Refined_Depends =>
          ((Formal_2,
            In_Out_Var,
            In_Private_Part.Var_3,
            In_Body.State_8) =>
              (Formal_1,
               In_Var,
               Var_2,
               In_Private_Part.State_7),

           (Formal_3,
            Out_Var,
            In_Body.Var_6,
            Var_8) =>
              (Formal_2,
               In_Out_Var,
               In_Private_Part.Var_3,
               In_Body.State_8)) is
   begin null; end OK_1;

   procedure OK_2
     (Formal_1 : in     Integer;
      Formal_2 : in out Integer;
      Formal_3 : out    Integer)
   is begin null; end OK_2;

   package In_Body
     with Abstract_State => (State_8 with Part_Of => State_2)
   is
      Var_6 : Integer;
   private
      Var_7 : Integer;
   end In_Body;

   package body In_Private_Part
     with Refined_State => (State_7 => Var_4)
   is end In_Private_Part;

   package body In_Body
     with Refined_State => (State_8 => Var_7)
   is end In_Body;

   Var_8 : Integer;
end Semantics;

-----------------
-- Compilation --
-----------------

$ gcc -c -gnat12 -gnatd.V semantics.adb

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

2013-10-14  Hristian Kirtchev  <kirtchev@adacore.com>

	* sem_ch6.adb (Analyze_Subprogram_Body_Contract): Add processing
	for pragma Refined_State.
	* sem_ch13.adb (Analyze_Aspect_Specifications): Add processing
	for aspect Refined_Depends.
	* sem_prag.adb (Analyze_Contract_Cases_In_Decl_Part):
	Use Find_Related_Subprogram_Or_Body to find the related
	context. Use the current scope when determining whether to
	ensure proper visibility.
	(Analyze_Depends_In_Decl_Part):
	Add local variable Spec_Id. Update the comment on usage of
	Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
	related context. Extract the corresponding spec of the body
	(if any). Use the current scope when determining when to
	ensure proper visibility.
	(Analyze_Global_In_Decl_Part):
	Add local variable Spec_Id. Update the comment on usage of
	Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
	related context. Extract the corresponding spec of the body
	(if any). Use the current scope when determining when to
	ensure proper visibility.
	(Analyze_Global_Item): Use the
	entity of the subprogram spec when performing formal parameter
	checks. Perform state-related checks.
	(Analyze_Input_Output):
	Use Is_Attribute_Result to detect 'Result. Query the
	entity of a subprogram spec when verifying the prefix of
	'Result. Perform state-related checks.	(Analyze_Pragma):
	Merge the analysis of Refined_Depends and Refined_Global.
	(Analyze_Refined_Depends_In_Decl_Part): Provide implemenation.
	(Analyze_Refined_Global_In_Decl_Part): Move state-related checks
	to the body of Analyze_Global_In_Decl_Part. Rename local constant
	List to Items.	(Analyze_Refined_Pragma): Remove circuitry to
	find the proper context, use Find_Related_Subprogram_Or_Body
	instead.
	(Check_Function_Return): Query the entity of
	the subprogram spec when verifying the use of 'Result.
	(Check_In_Out_States, Check_Input_States, Check_Output_States):
	Avoid using Has_Null_Refinement to detect a state with
	a non-null refinement, use the Refinement_Constituents
	list instead.
	(Check_Matching_Constituent): Remove initialization code.
	(Check_Mode_Restriction_In_Function): Use the entity of the subprogram
	spec when verifying mode usage in functions.
	(Collect_Global_Items): New routine.
	(Collect_Subprogram_Inputs_Outputs): Add local
	variable Spec_Id. Add circuitry for bodies-as-specs. Use
	pragma Refined_Global when collecting for a body.
	(Create_Or_Modify_Clause): Use the location of the
	clause. Rename local variable Clause to New_Clause to avoid
	confusion and update all occurrences.  Use Is_Attribute_Result
	to detect 'Result.
	(Find_Related_Subprogram): Removed.
	(Find_Related_Subprogram_Or_Body): New routine.
	(Is_Part_Of): Move routine to top level.
	(Normalize_Clause): Update the
	comment on usage. The routine can now normalize a clause with
	multiple outputs by splitting it.
	(Collect_Global_Items):
	Rename local constant List to Items. Remove the check for
	a null list.
	(Requires_Profile_Installation): Removed.
	(Split_Multiple_Outputs): New routine.
	* sem_prag.ads: Update the comments on usage of various
	pragma-related analysis routines.
	* sem_util.adb (Contains_Refined_State): The routine can now
	process pragma [Refined_]Depends.
	(Has_Refined_State): Removed.
	(Has_State_In_Dependency): New routine.
	(Has_State_In_Global): New routine.
	(Is_Attribute_Result): New routine.
	* sem_util.ads (Is_Attribute_Result): New routine.

Attachment: difs
Description: Text document


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