exp_util.adb (Side_Effect_Free): For CodePeer (only) treat uses of 'Image and related...
authorSteve Baird <baird@adacore.com>
Wed, 6 Sep 2017 12:01:13 +0000 (12:01 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 6 Sep 2017 12:01:13 +0000 (14:01 +0200)
2017-09-06  Steve Baird  <baird@adacore.com>

* exp_util.adb (Side_Effect_Free): For CodePeer (only) treat
uses of 'Image and related attributes as having side effects in
order to avoid replicating such uses.
* pprint.ads (Expression_Image) Add new generic formal flag
Hide_Temp_Derefs.  The flag defaults to False; CodePeer will
(eventually) override the default.
* pprint.adb (Expression_Image) If the new flag is set, then
suppress the ".all" suffix when displaying a dereference whose
prefix is a use of a value-capturing compiler temp of the sort
generated by Expr_Util.Remove_Side_Effects .
* exp_attr.adb, g-catiio.adb, inline.adb, sem_attr.adb, sem_ch13.adb,
sem_ch7.adb, sem_dim.adb, sem_util.adb, sem_util.ads, sem_warn.adb:
Minor reformatting.
* inline.adb: Minor wording change.

From-SVN: r251784

14 files changed:
gcc/ada/ChangeLog
gcc/ada/exp_attr.adb
gcc/ada/exp_util.adb
gcc/ada/g-catiio.adb
gcc/ada/inline.adb
gcc/ada/pprint.adb
gcc/ada/pprint.ads
gcc/ada/sem_attr.adb
gcc/ada/sem_ch13.adb
gcc/ada/sem_ch7.adb
gcc/ada/sem_dim.adb
gcc/ada/sem_util.adb
gcc/ada/sem_util.ads
gcc/ada/sem_warn.adb

index fd11670e146f5921408db5fa802f57c0ebbceb7b..b7a8679916590b8d8b22af3fa6e5d31bf4dea2dc 100644 (file)
@@ -1,3 +1,20 @@
+2017-09-06  Steve Baird  <baird@adacore.com>
+
+       * exp_util.adb (Side_Effect_Free): For CodePeer (only) treat
+       uses of 'Image and related attributes as having side effects in
+       order to avoid replicating such uses.
+       * pprint.ads (Expression_Image) Add new generic formal flag
+       Hide_Temp_Derefs.  The flag defaults to False; CodePeer will
+       (eventually) override the default.
+       * pprint.adb (Expression_Image) If the new flag is set, then
+       suppress the ".all" suffix when displaying a dereference whose
+       prefix is a use of a value-capturing compiler temp of the sort
+       generated by Expr_Util.Remove_Side_Effects .
+       * exp_attr.adb, g-catiio.adb, inline.adb, sem_attr.adb, sem_ch13.adb,
+       sem_ch7.adb, sem_dim.adb, sem_util.adb, sem_util.ads, sem_warn.adb:
+       Minor reformatting.
+       * inline.adb: Minor wording change.
+
 2017-09-06  Eric Botcazou  <ebotcazou@adacore.com>
 
        * sem_ch7.adb: Update comment.
index 60a975fe049bff3cd8b5a4e8fd3d30e8a4783740..ce115b98327ec400b0d72b9c15ecdf48e0fc99c6 100644 (file)
@@ -3613,6 +3613,7 @@ package body Exp_Attr is
       --  Image attribute is handled in separate unit Exp_Imgv
 
       when Attribute_Image =>
+
          --  Leave attribute unexpanded in CodePeer mode: the gnat2scil
          --  back-end knows how to handle this attribute directly.
 
@@ -3620,7 +3621,7 @@ package body Exp_Attr is
             return;
          end if;
 
-         Exp_Imgv.Expand_Image_Attribute (N);
+         Expand_Image_Attribute (N);
 
       ---------
       -- Img --
@@ -3629,7 +3630,7 @@ package body Exp_Attr is
       --  X'Img is expanded to typ'Image (X), where typ is the type of X
 
       when Attribute_Img =>
-         Exp_Imgv.Expand_Image_Attribute (N);
+         Expand_Image_Attribute (N);
 
       -----------
       -- Input --
@@ -6886,13 +6887,13 @@ package body Exp_Attr is
          elsif Is_Record_Type (Ftyp)
            and then Present (Declaration_Node (Ftyp))
            and then Nkind (Type_Definition (Declaration_Node (Ftyp))) =
-                                                        N_Record_Definition
+                      N_Record_Definition
          then
             Rewrite (N,
               Make_Function_Call (Loc,
                 Name                   =>
                   New_Occurrence_Of (Build_Record_VS_Func (Ftyp, N), Loc),
-              Parameter_Associations => New_List (Pref)));
+                Parameter_Associations => New_List (Pref)));
 
          --  Other record types or types with discriminants
 
index baffe28ad69a54f0f143d8d5fb0f8ce6e58aad63..10d9b1d1c826a62f980a6f676c6ba08d79932832 100644 (file)
@@ -12901,12 +12901,51 @@ package body Exp_Util is
          --  Is this right? what about x'first where x is a variable???
 
          when N_Attribute_Reference =>
-            return
-              Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
-                and then Attribute_Name (N) /= Name_Input
-                and then (Is_Entity_Name (Prefix (N))
-                           or else Side_Effect_Free
-                                     (Prefix (N), Name_Req, Variable_Ref));
+            Attribute_Reference : declare
+
+               function Side_Effect_Free_Attribute
+                 (Attribute_Name : Name_Id) return Boolean;
+               --  Returns True if evaluation of the given attribute is
+               --  considered side-effect free (independent of prefix and
+               --  arguments).
+
+               --------------------------------
+               -- Side_Effect_Free_Attribute --
+               --------------------------------
+
+               function Side_Effect_Free_Attribute
+                 (Attribute_Name : Name_Id) return Boolean
+               is
+               begin
+                  case Attribute_Name is
+                     when Name_Input =>
+                        return False;
+
+                     when Name_Image
+                        | Name_Img
+                        | Name_Wide_Image
+                        | Name_Wide_Wide_Image
+                     =>
+                        --  CodePeer doesn't want to see replicated copies of
+                        --  'Image calls.
+
+                        return not CodePeer_Mode;
+
+                     when others =>
+                        return True;
+                  end case;
+               end Side_Effect_Free_Attribute;
+
+            --  Start of processing for Attribute_Reference
+
+            begin
+               return
+                 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
+                   and then Side_Effect_Free_Attribute (Attribute_Name (N))
+                   and then (Is_Entity_Name (Prefix (N))
+                              or else Side_Effect_Free
+                                        (Prefix (N), Name_Req, Variable_Ref));
+            end Attribute_Reference;
 
          --  A binary operator is side effect free if and both operands are
          --  side effect free. For this purpose binary operators include
index 17ce098ab9eea9ead3d0eb1c16aff1af891bd1e3..6677a9b1b847e256e74e7bf7dd40d934b3cd6c16 100644 (file)
@@ -574,7 +574,7 @@ package body GNAT.Calendar.Time_IO is
        Time    : out Ada.Calendar.Time;
        Success : out Boolean)
    is
-      Index                 : Positive := Date'First;
+      Index : Positive := Date'First;
       --  The current character scan index. After a call to Advance, Index
       --  points to the next character.
 
@@ -582,7 +582,7 @@ package body GNAT.Calendar.Time_IO is
       --  An exception used to signal that the scan pointer has reached the
       --  end of the source string.
 
-      Wrong_Syntax          : exception;
+      Wrong_Syntax : exception;
       --  An exception used to signal that the scan pointer has reached an
       --  unexpected character in the source string.
 
@@ -815,20 +815,21 @@ package body GNAT.Calendar.Time_IO is
 
       Date_Separator : constant Character := '-';
       Hour_Separator : constant Character := ':';
-      Day            : Day_Number;
-      Month          : Month_Number;
-      Year           : Year_Number;
-      Hour           : Hour_Number     := 0;
-      Minute         : Minute_Number   := 0;
-      Second         : Second_Number   := 0;
-      Subsec         : Second_Duration := 0.0;
-
-      Local_Hour     : Hour_Number     := 0;
-      Local_Minute   : Minute_Number   := 0;
-      Local_Sign     : Character       := ' ';
-      Local_Disp     : Duration;
-
-      Sep_Required   : Boolean := False;
+
+      Day          : Day_Number;
+      Month        : Month_Number;
+      Year         : Year_Number;
+      Hour         : Hour_Number     := 0;
+      Minute       : Minute_Number   := 0;
+      Second       : Second_Number   := 0;
+      Subsec       : Second_Duration := 0.0;
+
+      Local_Hour   : Hour_Number     := 0;
+      Local_Minute : Minute_Number   := 0;
+      Local_Sign   : Character       := ' ';
+      Local_Disp   : Duration;
+
+      Sep_Required : Boolean := False;
       --  True if a separator is seen (and therefore required after it!)
 
    begin
@@ -929,14 +930,16 @@ package body GNAT.Calendar.Time_IO is
       --  Compute time with positive local displacement
 
       elsif Local_Sign = '+' then
-         Time := Time_Of (Year, Month, Day, Hour, Minute, Second, Subsec)
-                   - Local_Disp;
+         Time :=
+           Time_Of (Year, Month, Day, Hour, Minute, Second, Subsec) -
+             Local_Disp;
 
       --  Compute time with negative local displacement
 
       elsif Local_Sign = '-' then
-         Time := Time_Of (Year, Month, Day, Hour, Minute, Second, Subsec)
-                   + Local_Disp;
+         Time :=
+           Time_Of (Year, Month, Day, Hour, Minute, Second, Subsec) +
+             Local_Disp;
       end if;
 
       --  Notify that the input string was successfully parsed
@@ -944,8 +947,9 @@ package body GNAT.Calendar.Time_IO is
       Success := True;
 
    exception
-      when End_Of_Source_Reached |
-           Wrong_Syntax          =>
+      when End_Of_Source_Reached
+         | Wrong_Syntax
+      =>
          Success := False;
    end Parse_ISO_8861_UTC;
 
index 15efcef5519cd28cc3bbd7dad6e5a71d04f0da5a..70d1f84866a4f968cfb97328b9bacdba35fdb4c8 100644 (file)
@@ -1607,7 +1607,6 @@ package body Inline is
       --------------------------
 
       procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
-
          procedure Generate_Subprogram_Body
            (N              : Node_Id;
             Body_To_Inline : out Node_Id);
@@ -1683,11 +1682,10 @@ package body Inline is
             Save_Env (Scope (Current_Scope), Scope (Current_Scope));
          end if;
 
-         --  We need to capture references to the formals in order
-         --  to substitute the actuals at the point of inlining, i.e.
-         --  instantiation. To treat the formals as globals to the body to
-         --  inline, we nest it within a dummy parameterless subprogram,
-         --  declared within the real one.
+         --  Capture references to formals in order to substitute the actuals
+         --  at the point of inlining or instantiation. To treat the formals
+         --  as globals to the body to inline, nest the body within a dummy
+         --  parameterless subprogram, declared within the real one.
 
          Generate_Subprogram_Body (N, Original_Body);
          Body_To_Analyze := Copy_Generic_Node (Original_Body, Empty, False);
@@ -1730,8 +1728,7 @@ package body Inline is
       -- Can_Split_Unconstrained_Function --
       --------------------------------------
 
-      function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean
-      is
+      function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean is
          Ret_Node : constant Node_Id :=
                       First (Statements (Handled_Statement_Sequence (N)));
          D : Node_Id;
@@ -2925,7 +2922,7 @@ package body Inline is
             --  The semantic analyzer checked that frontend-inlined functions
             --  returning unconstrained types have no declarations and have
             --  a single extended return statement. As part of its processing
-            --  the function was split in two subprograms: a procedure P' and
+            --  the function was split into two subprograms: a procedure P' and
             --  a function F' that has a block with a call to procedure P' (see
             --  Split_Unconstrained_Function).
 
index fcfccd316f8aa7e2d12bccab660b23b8786a9142..912af392ec256ce756c7522d61b0002a8f53dc72 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2008-2016, Free Software Foundation, Inc.         --
+--          Copyright (C) 2008-2017, 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- --
@@ -325,22 +325,66 @@ package body Pprint is
                end if;
 
             when N_Explicit_Dereference =>
+               Explicit_Dereference : declare
+                  function Deref_Suffix return String;
+                  --  Usually returns ".all", but will return "" if
+                  --  Hide_Temp_Derefs is true and the prefix is a use of a
+                  --  not-from-source object declared as
+                  --    X : constant Some_Access_Type := Some_Expr'Reference;
+                  --  (as is sometimes done in Exp_Util.Remove_Side_Effects).
 
-               --  Return "Foo" instead of "Parameter_Block.Foo.all"
+                  ------------------
+                  -- Deref_Suffix --
+                  ------------------
 
-               if Hide_Parameter_Blocks
-                 and then Nkind (Prefix (Expr)) = N_Selected_Component
-                 and then Present (Etype (Prefix (Expr)))
-                 and then Is_Access_Type (Etype (Prefix (Expr)))
-                 and then Is_Param_Block_Component_Type (Etype (Prefix (Expr)))
-               then
-                  return Expr_Name (Selector_Name (Prefix (Expr)));
+                  function Deref_Suffix return String is
+                     Decl : Node_Id;
 
-               elsif Take_Prefix then
-                  return Expr_Name (Prefix (Expr)) & ".all";
-               else
-                  return ".all";
-               end if;
+                  begin
+                     if Hide_Temp_Derefs
+                       and then Nkind (Prefix (Expr)) = N_Identifier
+                       and then Nkind (Entity (Prefix (Expr))) =
+                                  N_Defining_Identifier
+                     then
+                        Decl := Parent (Entity (Prefix (Expr)));
+
+                        if Present (Decl)
+                          and then Nkind (Decl) = N_Object_Declaration
+                          and then not Comes_From_Source (Decl)
+                          and then Constant_Present (Decl)
+                          and then Present (Sinfo.Expression (Decl))
+                          and then Nkind (Sinfo.Expression (Decl)) =
+                                     N_Reference
+                        then
+                           return "";
+                        end if;
+                     end if;
+
+                     --  The default case
+
+                     return ".all";
+                  end Deref_Suffix;
+
+               --  Start of processing for Explicit_Dereference
+
+               begin
+                  if Hide_Parameter_Blocks
+                    and then Nkind (Prefix (Expr)) = N_Selected_Component
+                    and then Present (Etype (Prefix (Expr)))
+                    and then Is_Access_Type (Etype (Prefix (Expr)))
+                    and then Is_Param_Block_Component_Type
+                               (Etype (Prefix (Expr)))
+                  then
+                     --  Return "Foo" instead of "Parameter_Block.Foo.all"
+
+                     return Expr_Name (Selector_Name (Prefix (Expr)));
+
+                  elsif Take_Prefix then
+                     return Expr_Name (Prefix (Expr)) & Deref_Suffix;
+                  else
+                     return Deref_Suffix;
+                  end if;
+               end Explicit_Dereference;
 
             when N_Expanded_Name
                | N_Selected_Component
index 23160a04801a5f0a2bc2ad4f51146c624cd750a3..932d7bab9c61059783104c39176e9d32133e648c 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 2008-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 2008-2017, 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- --
@@ -50,6 +50,11 @@ package Pprint is
       --  If true, then "Parameter_Block.Field_Name.all" is
       --  instead displayed as "Field_Name".
 
+      Hide_Temp_Derefs : Boolean := False;
+      --  If true, then "Foo.all" is instead displayed as "Foo"
+      --  in the case where Foo is a compiler-generated constant
+      --  initialized to Some_Captured_Value'Reference.
+
    function Expression_Image
      (Expr    : Node_Id;
       Default : String) return String;
index 748df60736c181575319fb324a8ecae4ecb742f0..991f2b5aff94ddc0e7b98c2ac83436f9d6563041 100644 (file)
@@ -264,7 +264,7 @@ package body Sem_Attr is
       procedure Analyze_Image_Attribute (Str_Typ : Entity_Id);
       --  Common processing for attributes 'Img, 'Image, 'Wide_Image, and
       --  'Wide_Wide_Image. The routine checks that the prefix is valid and
-      --  sets the entity type to the one specified by Str_Typ (e.g.
+      --  sets the type of the attribute to the one specified by Str_Typ (e.g.
       --  Standard_String for 'Image and Standard_Wide_String for 'Wide_Image).
 
       procedure Bad_Attribute_For_Predicate;
@@ -1475,7 +1475,7 @@ package body Sem_Attr is
                if Ada_Version > Ada_2005 then
                   Error_Attr_P
                     ("prefix of % attribute must be a scalar type or a scalar "
-                      & "object name");
+                     & "object name");
                else
                   Error_Attr_P ("prefix of % attribute must be a scalar type");
                end if;
index 441dad584cc43544db4bac31f27e0265617c53cb..21abd063b8acc3b0f3406e828450b38964ac1f85 100644 (file)
@@ -12707,8 +12707,10 @@ package body Sem_Ch13 is
             declare
                A_Id : constant Aspect_Id := Get_Aspect_Id (ASN);
                Expr : constant Node_Id   := Expression (ASN);
+
             begin
                case A_Id is
+
                   --  For now we only deal with aspects that do not generate
                   --  subprograms, or that may mention current instances of
                   --  types. These will require special handling (???TBD).
index 3da7987fa57590caff52c330788cfa49d98ab86a..b0f6bd90f1aa2a9aa61d226f58ca1a4c20ba734b 100644 (file)
@@ -248,7 +248,6 @@ package body Sem_Ch7 is
       --------------------------
 
       procedure Hide_Public_Entities (Decls : List_Id) is
-
          function Has_Referencer
            (Decls     : List_Id;
             Top_Level : Boolean := False) return Boolean;
index d5f724d5e63534e6203363bf0fda1ef228ed2fc8..2b4b84319f8a68cd6b7e812fd51ebab983d7805a 100644 (file)
@@ -1200,7 +1200,6 @@ package body Sem_Dim is
             end if;
 
          when N_Unary_Op =>
-
             Analyze_Dimension_Unary_Op (N);
 
          when others =>
index 0440d89edd23f57d16d809d876346962f7925f6a..d20cafbe63b799878a50589f70818583139ad300 100644 (file)
@@ -14130,7 +14130,7 @@ package body Sem_Util is
 
    function Is_Object_Image (Prefix : Node_Id) return Boolean is
    begin
-      --  When the type of the prefix is not scalar then the prefix is not
+      --  When the type of the prefix is not scalar, then the prefix is not
       --  valid in any scenario.
 
       if not Is_Scalar_Type (Etype (Prefix)) then
@@ -14228,9 +14228,9 @@ package body Sem_Util is
                return not Nkind_In (Original_Node (N), N_Case_Expression,
                                                        N_If_Expression);
 
-            when N_Type_Conversion =>
-               --  A view conversion of a tagged object is an object reference
+            --  A view conversion of a tagged object is an object reference
 
+            when N_Type_Conversion =>
                return Is_Tagged_Type (Etype (Subtype_Mark (N)))
                  and then Is_Tagged_Type (Etype (Expression (N)))
                  and then Is_Object_Reference (Expression (N));
@@ -22569,6 +22569,7 @@ package body Sem_Util is
          if Ekind (Scop) = E_Protected_Type then
             return True;
          end if;
+
          Scop := Scope (Scop);
       end loop;
 
index 7d3bd0920d71ccc2a2aa15d917e2761bc783c63c..a80d3fc21d8bdcaa00551fe24d8dcce39ffdfcc5 100644 (file)
@@ -1672,7 +1672,7 @@ package Sem_Util is
    --  null component list.
 
    function Is_Object_Image (Prefix : Node_Id) return Boolean;
-   --  Returns true if an 'Image, 'Wide_Image, or 'Wide_Wide_Image attribute
+   --  Returns True if an 'Image, 'Wide_Image, or 'Wide_Wide_Image attribute
    --  is applied to a given object or named value prefix (see below).
 
    --  AI12-00124: The ARG has adopted the GNAT semantics of 'Img for scalar
index ecc47e4f24cbf9668abdd0e48283398eed636e31..9e1b2c3f3c290d5f55895dff4f006235d9787a1f 100644 (file)
@@ -1388,10 +1388,10 @@ package body Sem_Warn is
                   --  an expression with actions.
 
                   UR := Original_Node (UR);
-                  while Nkind (UR) = N_Type_Conversion
-                    or else Nkind (UR) = N_Qualified_Expression
-                    or else Nkind (UR) = N_Expression_With_Actions
-                    or else Nkind (UR) = N_Attribute_Reference
+                  while Nkind_In (UR, N_Attribute_Reference,
+                                      N_Expression_With_Actions,
+                                      N_Qualified_Expression,
+                                      N_Type_Conversion)
                   loop
                      if Nkind (UR) = N_Attribute_Reference then
                         UR := Prefix (UR);