------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ C H 1 1                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2019, 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.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
with Checks;   use Checks;
with Einfo;    use Einfo;
with Errout;   use Errout;
with Lib;      use Lib;
with Lib.Xref; use Lib.Xref;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Restrict; use Restrict;
with Rident;   use Rident;
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
with Sem_Aux;  use Sem_Aux;
with Sem_Ch5;  use Sem_Ch5;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Stand;    use Stand;

package body Sem_Ch11 is

   -----------------------------------
   -- Analyze_Exception_Declaration --
   -----------------------------------

   procedure Analyze_Exception_Declaration (N : Node_Id) is
      Id : constant Entity_Id := Defining_Identifier (N);
      PF : constant Boolean   := Is_Pure (Current_Scope);

   begin
      Generate_Definition         (Id);
      Enter_Name                  (Id);
      Set_Ekind                   (Id, E_Exception);
      Set_Etype                   (Id, Standard_Exception_Type);
      Set_Is_Statically_Allocated (Id);
      Set_Is_Pure                 (Id, PF);

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Id);
      end if;
   end Analyze_Exception_Declaration;

   --------------------------------
   -- Analyze_Exception_Handlers --
   --------------------------------

   procedure Analyze_Exception_Handlers (L : List_Id) is
      Handler : Node_Id;
      Choice  : Entity_Id;
      Id      : Node_Id;
      H_Scope : Entity_Id := Empty;

      procedure Check_Duplication (Id : Node_Id);
      --  Iterate through the identifiers in each handler to find duplicates

      function Others_Present return Boolean;
      --  Returns True if others handler is present

      -----------------------
      -- Check_Duplication --
      -----------------------

      procedure Check_Duplication (Id : Node_Id) is
         Handler   : Node_Id;
         Id1       : Node_Id;
         Id_Entity : Entity_Id := Entity (Id);

      begin
         if Present (Renamed_Entity (Id_Entity)) then
            Id_Entity := Renamed_Entity (Id_Entity);
         end if;

         Handler := First_Non_Pragma (L);
         while Present (Handler) loop
            Id1 := First (Exception_Choices (Handler));
            while Present (Id1) loop

               --  Only check against the exception choices which precede
               --  Id in the handler, since the ones that follow Id have not
               --  been analyzed yet and will be checked in a subsequent call.

               if Id = Id1 then
                  return;

               elsif Nkind (Id1) /= N_Others_Choice
                 and then
                   (Id_Entity = Entity (Id1)
                     or else (Id_Entity = Renamed_Entity (Entity (Id1))))
               then
                  if Handler /= Parent (Id) then
                     Error_Msg_Sloc := Sloc (Id1);
                     Error_Msg_NE ("exception choice duplicates &#", Id, Id1);

                  else
                     if Ada_Version = Ada_83
                       and then Comes_From_Source (Id)
                     then
                        Error_Msg_N
                          ("(Ada 83): duplicate exception choice&", Id);
                     end if;
                  end if;
               end if;

               Next_Non_Pragma (Id1);
            end loop;

            Next (Handler);
         end loop;
      end Check_Duplication;

      --------------------
      -- Others_Present --
      --------------------

      function Others_Present return Boolean is
         H : Node_Id;

      begin
         H := First (L);
         while Present (H) loop
            if Nkind (H) /= N_Pragma
              and then Nkind (First (Exception_Choices (H))) = N_Others_Choice
            then
               return True;
            end if;

            Next (H);
         end loop;

         return False;
      end Others_Present;

   --  Start of processing for Analyze_Exception_Handlers

   begin
      Handler := First (L);

      --  Pragma Restriction_Warnings has more related semantics than pragma
      --  Restrictions in that it flags exception handlers as violators. Note
      --  that the compiler must still generate handlers for certain critical
      --  scenarios such as finalization. As a result, these handlers should
      --  not be subjected to the restriction check when in warnings mode.

      if not Comes_From_Source (Handler)
        and then (Restriction_Warnings (No_Exception_Handlers)
                   or else Restriction_Warnings (No_Exception_Propagation)
                   or else Restriction_Warnings (No_Exceptions))
      then
         null;

      else
         Check_Restriction (No_Exceptions, Handler);
         Check_Restriction (No_Exception_Handlers, Handler);
      end if;

      --  Kill current remembered values, since we don't know where we were
      --  when the exception was raised.

      Kill_Current_Values;

      --  Loop through handlers (which can include pragmas)

      while Present (Handler) loop

         --  If pragma just analyze it

         if Nkind (Handler) = N_Pragma then
            Analyze (Handler);

         --  Otherwise we have a real exception handler

         else
            --  Deal with choice parameter. The exception handler is a
            --  declarative part for the choice parameter, so it constitutes a
            --  scope for visibility purposes. We create an entity to denote
            --  the whole exception part, and use it as the scope of all the
            --  choices, which may even have the same name without conflict.
            --  This scope plays no other role in expansion or code generation.

            Choice := Choice_Parameter (Handler);

            if Present (Choice) then
               Set_Local_Raise_Not_OK (Handler);

               if Comes_From_Source (Choice) then
                  Check_Restriction (No_Exception_Propagation, Choice);
                  Set_Debug_Info_Needed (Choice);
               end if;

               if No (H_Scope) then
                  H_Scope :=
                    New_Internal_Entity
                     (E_Block, Current_Scope, Sloc (Choice), 'E');
                  Set_Is_Exception_Handler (H_Scope);
               end if;

               Push_Scope (H_Scope);
               Set_Etype (H_Scope, Standard_Void_Type);

               Enter_Name (Choice);
               Set_Ekind (Choice, E_Variable);

               if RTE_Available (RE_Exception_Occurrence) then
                  Set_Etype (Choice, RTE (RE_Exception_Occurrence));
               end if;

               Generate_Definition (Choice);

               --  Indicate that choice has an initial value, since in effect
               --  this field is assigned an initial value by the exception.
               --  We also consider that it is modified in the source.

               Set_Has_Initial_Value (Choice, True);
               Set_Never_Set_In_Source (Choice, False);
            end if;

            Id := First (Exception_Choices (Handler));
            while Present (Id) loop
               if Nkind (Id) = N_Others_Choice then
                  if Present (Next (Id))
                    or else Present (Next (Handler))
                    or else Present (Prev (Id))
                  then
                     Error_Msg_N ("OTHERS must appear alone and last", Id);
                  end if;

               else
                  Analyze (Id);

                  --  In most cases the choice has already been analyzed in
                  --  Analyze_Handled_Statement_Sequence, in order to expand
                  --  local handlers. This advance analysis does not take into
                  --  account the case in which a choice has the same name as
                  --  the choice parameter of the handler, which may hide an
                  --  outer exception. This pathological case appears in ACATS
                  --  B80001_3.adb, and requires an explicit check to verify
                  --  that the id is not hidden.

                  if not Is_Entity_Name (Id)
                    or else Ekind (Entity (Id)) /= E_Exception
                    or else
                      (Nkind (Id) = N_Identifier
                        and then Chars (Id) = Chars (Choice))
                  then
                     Error_Msg_N ("exception name expected", Id);

                  else
                     --  Emit a warning at the declaration level when a local
                     --  exception is never raised explicitly.

                     if Warn_On_Redundant_Constructs
                       and then not Is_Raised (Entity (Id))
                       and then Scope (Entity (Id)) = Current_Scope
                     then
                        Error_Msg_NE
                          ("exception & is never raised?r?", Entity (Id), Id);
                     end if;

                     if Present (Renamed_Entity (Entity (Id))) then
                        if Entity (Id) = Standard_Numeric_Error then
                           Check_Restriction (No_Obsolescent_Features, Id);

                           if Warn_On_Obsolescent_Feature then
                              Error_Msg_N
                                ("Numeric_Error is an " &
                                 "obsolescent feature (RM J.6(1))?j?", Id);
                              Error_Msg_N
                                ("\use Constraint_Error instead?j?", Id);
                           end if;
                        end if;
                     end if;

                     Check_Duplication (Id);

                     --  Check for exception declared within generic formal
                     --  package (which is illegal, see RM 11.2(8))

                     declare
                        Ent  : Entity_Id := Entity (Id);
                        Scop : Entity_Id;

                     begin
                        if Present (Renamed_Entity (Ent)) then
                           Ent := Renamed_Entity (Ent);
                        end if;

                        Scop := Scope (Ent);
                        while Scop /= Standard_Standard
                          and then Ekind (Scop) = E_Package
                        loop
                           if Nkind (Declaration_Node (Scop)) =
                                           N_Package_Specification
                             and then
                               Nkind (Original_Node (Parent
                                 (Declaration_Node (Scop)))) =
                                           N_Formal_Package_Declaration
                           then
                              Error_Msg_NE
                                ("exception& is declared in generic formal "
                                 & "package", Id, Ent);
                              Error_Msg_N
                                ("\and therefore cannot appear in handler "
                                 & "(RM 11.2(8))", Id);
                              exit;

                           --  If the exception is declared in an inner
                           --  instance, nothing else to check.

                           elsif Is_Generic_Instance (Scop) then
                              exit;
                           end if;

                           Scop := Scope (Scop);
                        end loop;
                     end;
                  end if;
               end if;

               Next (Id);
            end loop;

            --  Check for redundant handler (has only raise statement) and is
            --  either an others handler, or is a specific handler when no
            --  others handler is present.

            if Warn_On_Redundant_Constructs
              and then List_Length (Statements (Handler)) = 1
              and then Nkind (First (Statements (Handler))) = N_Raise_Statement
              and then No (Name (First (Statements (Handler))))
              and then (not Others_Present
                         or else Nkind (First (Exception_Choices (Handler))) =
                                              N_Others_Choice)
            then
               Error_Msg_N
                 ("useless handler contains only a reraise statement?r?",
                  Handler);
            end if;

            --  Now analyze the statements of this handler

            Analyze_Statements (Statements (Handler));

            --  If a choice was present, we created a special scope for it, so
            --  this is where we pop that special scope to get rid of it.

            if Present (Choice) then
               End_Scope;
            end if;
         end if;

         Next (Handler);
      end loop;
   end Analyze_Exception_Handlers;

   --------------------------------
   -- Analyze_Handled_Statements --
   --------------------------------

   procedure Analyze_Handled_Statements (N : Node_Id) is
      Handlers : constant List_Id := Exception_Handlers (N);
      Handler  : Node_Id;
      Choice   : Node_Id;

   begin
      if Present (Handlers) then
         Kill_All_Checks;
      end if;

      --  We are now going to analyze the statements and then the exception
      --  handlers. We certainly need to do things in this order to get the
      --  proper sequential semantics for various warnings.

      --  However, there is a glitch. When we process raise statements, an
      --  optimization is to look for local handlers and specialize the code
      --  in this case.

      --  In order to detect if a handler is matching, we must have at least
      --  analyzed the choices in the proper scope so that proper visibility
      --  analysis is performed. Hence we analyze just the choices first,
      --  before we analyze the statement sequence.

      Handler := First_Non_Pragma (Handlers);
      while Present (Handler) loop
         Choice := First_Non_Pragma (Exception_Choices (Handler));
         while Present (Choice) loop
            Analyze (Choice);
            Next_Non_Pragma (Choice);
         end loop;

         Next_Non_Pragma (Handler);
      end loop;

      --  Analyze statements in sequence

      Analyze_Statements (Statements (N));

      --  If the current scope is a subprogram, entry or task body or declare
      --  block then this is the right place to check for hanging useless
      --  assignments from the statement sequence. Skip this in the body of a
      --  postcondition, since in that case there are no source references, and
      --  we need to preserve deferred references from the enclosing scope.

      if ((Is_Subprogram (Current_Scope) or else Is_Entry (Current_Scope))
           and then Chars (Current_Scope) /= Name_uPostconditions)
         or else Ekind_In (Current_Scope, E_Block, E_Task_Type)
      then
         Warn_On_Useless_Assignments (Current_Scope);
      end if;

      --  Deal with handlers or AT END proc

      if Present (Handlers) then
         Analyze_Exception_Handlers (Handlers);
      elsif Present (At_End_Proc (N)) then
         Analyze (At_End_Proc (N));
      end if;
   end Analyze_Handled_Statements;

   ------------------------------
   -- Analyze_Raise_Expression --
   ------------------------------

   procedure Analyze_Raise_Expression (N : Node_Id) is
      Exception_Id   : constant Node_Id := Name (N);
      Exception_Name : Entity_Id        := Empty;

   begin
      if Comes_From_Source (N) then
         Check_Compiler_Unit ("raise expression", N);
      end if;

      Check_SPARK_05_Restriction ("raise expression is not allowed", N);

      --  Check exception restrictions on the original source

      if Comes_From_Source (N) then
         Check_Restriction (No_Exceptions, N);
      end if;

      Analyze (Exception_Id);

      if Is_Entity_Name (Exception_Id) then
         Exception_Name := Entity (Exception_Id);
      end if;

      if No (Exception_Name)
        or else Ekind (Exception_Name) /= E_Exception
      then
         Error_Msg_N
           ("exception name expected in raise statement", Exception_Id);
      else
         Set_Is_Raised (Exception_Name);
      end if;

      --  Deal with RAISE WITH case

      if Present (Expression (N)) then
         Analyze_And_Resolve (Expression (N), Standard_String);
      end if;

      --  Check obsolescent use of Numeric_Error

      if Exception_Name = Standard_Numeric_Error then
         Check_Restriction (No_Obsolescent_Features, Exception_Id);
      end if;

      --  Kill last assignment indication

      Kill_Current_Values (Last_Assignment_Only => True);

      --  Raise_Type is compatible with all other types so that the raise
      --  expression is legal in any expression context. It will be eventually
      --  replaced by the concrete type imposed by the context.

      Set_Etype (N, Raise_Type);
   end Analyze_Raise_Expression;

   -----------------------------
   -- Analyze_Raise_Statement --
   -----------------------------

   procedure Analyze_Raise_Statement (N : Node_Id) is
      Exception_Id   : constant Node_Id := Name (N);
      Exception_Name : Entity_Id        := Empty;
      P              : Node_Id;
      Par            : Node_Id;

   begin
      if Comes_From_Source (N) then
         Check_SPARK_05_Restriction ("raise statement is not allowed", N);
      end if;

      Check_Unreachable_Code (N);

      --  Check exception restrictions on the original source

      if Comes_From_Source (N) then
         Check_Restriction (No_Exceptions, N);
      end if;

      --  Check for useless assignment to OUT or IN OUT scalar preceding the
      --  raise. Right now only look at assignment statements, could do more???

      if Is_List_Member (N) then
         declare
            P : Node_Id;
            L : Node_Id;

         begin
            P := Prev (N);

            --  Skip past null statements and pragmas

            while Present (P)
              and then Nkind_In (P, N_Null_Statement, N_Pragma)
            loop
               P := Prev (P);
            end loop;

            --  See if preceding statement is an assignment

            if Present (P) and then Nkind (P) = N_Assignment_Statement then
               L := Name (P);

               --  Give warning for assignment to scalar formal

               if Is_Scalar_Type (Etype (L))
                 and then Is_Entity_Name (L)
                 and then Is_Formal (Entity (L))

                 --  Do this only for parameters to the current subprogram.
                 --  This avoids some false positives for the nested case.

                 and then Nearest_Dynamic_Scope (Current_Scope) =
                                                        Scope (Entity (L))

               then
                  --  Don't give warning if we are covered by an exception
                  --  handler, since this may result in false positives, since
                  --  the handler may handle the exception and return normally.

                  --  First find the enclosing handled sequence of statements
                  --  (note, we could also look for a handler in an outer block
                  --  but currently we don't, and in that case we'll emit the
                  --  warning).

                  Par := N;
                  loop
                     Par := Parent (Par);
                     exit when Nkind (Par) = N_Handled_Sequence_Of_Statements;
                  end loop;

                  --  See if there is a handler, give message if not

                  if No (Exception_Handlers (Par)) then
                     Error_Msg_N
                       ("assignment to pass-by-copy formal "
                        & "may have no effect??", P);
                     Error_Msg_N
                       ("\RAISE statement may result in abnormal return "
                        & "(RM 6.4.1(17))??", P);
                  end if;
               end if;
            end if;
         end;
      end if;

      --  Reraise statement

      if No (Exception_Id) then
         P := Parent (N);
         while not Nkind_In (P, N_Exception_Handler,
                                N_Subprogram_Body,
                                N_Package_Body,
                                N_Task_Body,
                                N_Entry_Body)
         loop
            P := Parent (P);
         end loop;

         if Nkind (P) /= N_Exception_Handler then
            Error_Msg_N
              ("reraise statement must appear directly in a handler", N);

         --  If a handler has a reraise, it cannot be the target of a local
         --  raise (goto optimization is impossible), and if the no exception
         --  propagation restriction is set, this is a violation.

         else
            Set_Local_Raise_Not_OK (P);

            --  Do not check the restriction if the reraise statement is part
            --  of the code generated for an AT-END handler. That's because
            --  if the restriction is actually active, we never generate this
            --  raise anyway, so the apparent violation is bogus.

            if not From_At_End (N) then
               Check_Restriction (No_Exception_Propagation, N);
            end if;
         end if;

      --  Normal case with exception id present

      else
         Analyze (Exception_Id);

         if Is_Entity_Name (Exception_Id) then
            Exception_Name := Entity (Exception_Id);
         end if;

         if No (Exception_Name)
           or else Ekind (Exception_Name) /= E_Exception
         then
            Error_Msg_N
              ("exception name expected in raise statement", Exception_Id);
         else
            Set_Is_Raised (Exception_Name);
         end if;

         --  Deal with RAISE WITH case

         if Present (Expression (N)) then
            Analyze_And_Resolve (Expression (N), Standard_String);
         end if;
      end if;

      --  Check obsolescent use of Numeric_Error

      if Exception_Name = Standard_Numeric_Error then
         Check_Restriction (No_Obsolescent_Features, Exception_Id);
      end if;

      --  Kill last assignment indication

      Kill_Current_Values (Last_Assignment_Only => True);
   end Analyze_Raise_Statement;

   -----------------------------
   -- Analyze_Raise_xxx_Error --
   -----------------------------

   --  Normally, the Etype is already set (when this node is used within
   --  an expression, since it is copied from the node which it rewrites).
   --  If this node is used in a statement context, then we set the type
   --  Standard_Void_Type. This is used both by Gigi and by the front end
   --  to distinguish the statement use and the subexpression use.

   --  The only other required processing is to take care of the Condition
   --  field if one is present.

   procedure Analyze_Raise_xxx_Error (N : Node_Id) is

      function Same_Expression (C1, C2 : Node_Id) return Boolean;
      --  It often occurs that two identical raise statements are generated in
      --  succession (for example when dynamic elaboration checks take place on
      --  separate expressions in a call). If the two statements are identical
      --  according to the simple criterion that follows, the raise is
      --  converted into a null statement.

      ---------------------
      -- Same_Expression --
      ---------------------

      function Same_Expression (C1, C2 : Node_Id) return Boolean is
      begin
         if No (C1) and then No (C2) then
            return True;

         elsif Is_Entity_Name (C1) and then Is_Entity_Name (C2) then
            return Entity (C1) = Entity (C2);

         elsif Nkind (C1) /= Nkind (C2) then
            return False;

         elsif Nkind (C1) in N_Unary_Op then
            return Same_Expression (Right_Opnd (C1), Right_Opnd (C2));

         elsif Nkind (C1) in N_Binary_Op then
            return Same_Expression (Left_Opnd (C1),  Left_Opnd (C2))
                     and then
                   Same_Expression (Right_Opnd (C1), Right_Opnd (C2));

         elsif Nkind (C1) = N_Null then
            return True;

         else
            return False;
         end if;
      end Same_Expression;

   --  Start of processing for Analyze_Raise_xxx_Error

   begin
      if Nkind (Original_Node (N)) = N_Raise_Statement then
         Check_SPARK_05_Restriction ("raise statement is not allowed", N);
      end if;

      if No (Etype (N)) then
         Set_Etype (N, Standard_Void_Type);
      end if;

      if Present (Condition (N)) then
         Analyze_And_Resolve (Condition (N), Standard_Boolean);
      end if;

      --  Deal with static cases in obvious manner

      if Nkind (Condition (N)) = N_Identifier then
         if Entity (Condition (N)) = Standard_True then
            Set_Condition (N, Empty);

         elsif Entity (Condition (N)) = Standard_False then
            Rewrite (N, Make_Null_Statement (Sloc (N)));
         end if;
      end if;

      --  Remove duplicate raise statements. Note that the previous one may
      --  already have been removed as well.

      if not Comes_From_Source (N)
        and then Nkind (N) /= N_Null_Statement
        and then Is_List_Member (N)
        and then Present (Prev (N))
        and then Nkind (N) = Nkind (Original_Node (Prev (N)))
        and then Same_Expression
                   (Condition (N), Condition (Original_Node (Prev (N))))
      then
         Rewrite (N, Make_Null_Statement (Sloc (N)));
      end if;
   end Analyze_Raise_xxx_Error;

end Sem_Ch11;
