1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2024, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree
; use Atree
;
27 with Checks
; use Checks
;
28 with Einfo
; use Einfo
;
29 with Einfo
.Entities
; use Einfo
.Entities
;
30 with Einfo
.Utils
; use Einfo
.Utils
;
31 with Errout
; use Errout
;
33 with Lib
.Xref
; use Lib
.Xref
;
34 with Namet
; use Namet
;
35 with Nlists
; use Nlists
;
36 with Nmake
; use Nmake
;
38 with Restrict
; use Restrict
;
39 with Rident
; use Rident
;
40 with Rtsfind
; use Rtsfind
;
42 with Sem_Aux
; use Sem_Aux
;
43 with Sem_Ch5
; use Sem_Ch5
;
44 with Sem_Ch8
; use Sem_Ch8
;
45 with Sem_Ch13
; use Sem_Ch13
;
46 with Sem_Res
; use Sem_Res
;
47 with Sem_Util
; use Sem_Util
;
48 with Sem_Warn
; use Sem_Warn
;
49 with Sinfo
; use Sinfo
;
50 with Sinfo
.Nodes
; use Sinfo
.Nodes
;
51 with Sinfo
.Utils
; use Sinfo
.Utils
;
52 with Stand
; use Stand
;
53 with Warnsw
; use Warnsw
;
55 package body Sem_Ch11
is
57 -----------------------------------
58 -- Analyze_Exception_Declaration --
59 -----------------------------------
61 procedure Analyze_Exception_Declaration
(N
: Node_Id
) is
62 Id
: constant Entity_Id
:= Defining_Identifier
(N
);
63 PF
: constant Boolean := Is_Pure
(Current_Scope
);
66 Generate_Definition
(Id
);
68 Mutate_Ekind
(Id
, E_Exception
);
69 Set_Etype
(Id
, Standard_Exception_Type
);
70 Set_Is_Statically_Allocated
(Id
);
73 Analyze_Aspect_Specifications
(N
, Id
);
74 end Analyze_Exception_Declaration
;
76 --------------------------------
77 -- Analyze_Exception_Handlers --
78 --------------------------------
80 procedure Analyze_Exception_Handlers
(L
: List_Id
) is
84 H_Scope
: Entity_Id
:= Empty
;
86 procedure Check_Duplication
(Id
: Node_Id
);
87 -- Iterate through the identifiers in each handler to find duplicates
89 function Others_Present
return Boolean;
90 -- Returns True if others handler is present
92 -----------------------
93 -- Check_Duplication --
94 -----------------------
96 procedure Check_Duplication
(Id
: Node_Id
) is
99 Id_Entity
: Entity_Id
:= Entity
(Id
);
102 if Present
(Renamed_Entity
(Id_Entity
)) then
103 Id_Entity
:= Renamed_Entity
(Id_Entity
);
106 Handler
:= First_Non_Pragma
(L
);
107 while Present
(Handler
) loop
108 Id1
:= First
(Exception_Choices
(Handler
));
109 while Present
(Id1
) loop
111 -- Only check against the exception choices which precede
112 -- Id in the handler, since the ones that follow Id have not
113 -- been analyzed yet and will be checked in a subsequent call.
118 elsif Nkind
(Id1
) /= N_Others_Choice
120 (Id_Entity
= Entity
(Id1
)
121 or else Id_Entity
= Renamed_Entity
(Entity
(Id1
)))
123 if Handler
/= Parent
(Id
) then
124 Error_Msg_Sloc
:= Sloc
(Id1
);
125 Error_Msg_NE
("exception choice duplicates &#", Id
, Id1
);
128 if Ada_Version
= Ada_83
129 and then Comes_From_Source
(Id
)
132 ("(Ada 83) duplicate exception choice&", Id
);
140 Next_Non_Pragma
(Handler
);
142 end Check_Duplication
;
148 function Others_Present
return Boolean is
152 H
:= First_Non_Pragma
(L
);
153 while Present
(H
) loop
154 if Nkind
(First
(Exception_Choices
(H
))) = N_Others_Choice
then
164 -- Start of processing for Analyze_Exception_Handlers
167 Handler
:= First
(L
);
169 -- Pragma Restriction_Warnings has more related semantics than pragma
170 -- Restrictions in that it flags exception handlers as violators. Note
171 -- that the compiler must still generate handlers for certain critical
172 -- scenarios such as finalization. As a result, these handlers should
173 -- not be subjected to the restriction check when in warnings mode.
175 if not Comes_From_Source
(Handler
)
176 and then (Restriction_Warnings
(No_Exception_Handlers
)
177 or else Restriction_Warnings
(No_Exception_Propagation
)
178 or else Restriction_Warnings
(No_Exceptions
))
183 Check_Restriction
(No_Exceptions
, Handler
);
184 Check_Restriction
(No_Exception_Handlers
, Handler
);
187 -- Kill current remembered values, since we don't know where we were
188 -- when the exception was raised.
192 -- Loop through handlers (which can include pragmas)
194 while Present
(Handler
) loop
196 -- If pragma just analyze it
198 if Nkind
(Handler
) = N_Pragma
then
201 -- Otherwise we have a real exception handler
204 -- Deal with choice parameter. The exception handler is a
205 -- declarative part for the choice parameter, so it constitutes a
206 -- scope for visibility purposes. We create an entity to denote
207 -- the whole exception part, and use it as the scope of all the
208 -- choices, which may even have the same name without conflict.
209 -- This scope plays no other role in expansion or code generation.
211 Choice
:= Choice_Parameter
(Handler
);
213 if Present
(Choice
) then
214 Set_Local_Raise_Not_OK
(Handler
);
216 if Comes_From_Source
(Choice
) then
217 Check_Restriction
(No_Exception_Propagation
, Choice
);
218 Set_Debug_Info_Needed
(Choice
);
224 (E_Block
, Current_Scope
, Sloc
(Choice
), 'E');
225 Set_Is_Exception_Handler
(H_Scope
);
228 Push_Scope
(H_Scope
);
229 Set_Etype
(H_Scope
, Standard_Void_Type
);
232 Mutate_Ekind
(Choice
, E_Variable
);
233 Set_Is_Not_Self_Hidden
(Choice
);
235 if RTE_Available
(RE_Exception_Occurrence
) then
236 Set_Etype
(Choice
, RTE
(RE_Exception_Occurrence
));
239 Generate_Definition
(Choice
);
241 -- Indicate that choice has an initial value, since in effect
242 -- this field is assigned an initial value by the exception.
243 -- We also consider that it is modified in the source.
245 Set_Has_Initial_Value
(Choice
, True);
246 Set_Never_Set_In_Source
(Choice
, False);
249 Id
:= First
(Exception_Choices
(Handler
));
250 while Present
(Id
) loop
251 if Nkind
(Id
) = N_Others_Choice
then
252 if Present
(Next
(Id
))
253 or else Present
(Next
(Handler
))
254 or else Present
(Prev
(Id
))
256 Error_Msg_N
("OTHERS must appear alone and last", Id
);
262 -- In most cases the choice has already been analyzed in
263 -- Analyze_Handled_Statement_Sequence, in order to expand
264 -- local handlers. This advance analysis does not take into
265 -- account the case in which a choice has the same name as
266 -- the choice parameter of the handler, which may hide an
267 -- outer exception. This pathological case appears in ACATS
268 -- B80001_3.adb, and requires an explicit check to verify
269 -- that the id is not hidden.
271 if not Is_Entity_Name
(Id
)
272 or else Ekind
(Entity
(Id
)) /= E_Exception
274 (Nkind
(Id
) = N_Identifier
275 and then Chars
(Id
) = Chars
(Choice
))
277 Error_Msg_N
("exception name expected", Id
);
280 -- Emit a warning at the declaration level when a local
281 -- exception is never raised explicitly.
283 if Warn_On_Redundant_Constructs
284 and then not Is_Raised
(Entity
(Id
))
285 and then Scope
(Entity
(Id
)) = Current_Scope
288 ("exception & is never raised?r?", Entity
(Id
), Id
);
291 if Present
(Renamed_Entity
(Entity
(Id
))) then
292 if Entity
(Id
) = Standard_Numeric_Error
then
293 Check_Restriction
(No_Obsolescent_Features
, Id
);
295 if Warn_On_Obsolescent_Feature
then
297 ("Numeric_Error is an " &
298 "obsolescent feature (RM J.6(1))?j?", Id
);
300 ("\use Constraint_Error instead?j?", Id
);
305 Check_Duplication
(Id
);
307 -- Check for exception declared within generic formal
308 -- package (which is illegal, see RM 11.2(8))
311 Ent
: Entity_Id
:= Entity
(Id
);
315 if Present
(Renamed_Entity
(Ent
)) then
316 Ent
:= Renamed_Entity
(Ent
);
320 while Scop
/= Standard_Standard
321 and then Ekind
(Scop
) = E_Package
323 if Nkind
(Declaration_Node
(Scop
)) =
324 N_Package_Specification
326 Nkind
(Original_Node
(Parent
327 (Declaration_Node
(Scop
)))) =
328 N_Formal_Package_Declaration
331 ("exception& is declared in generic formal "
332 & "package", Id
, Ent
);
334 ("\and therefore cannot appear in handler "
335 & "(RM 11.2(8))", Id
);
338 -- If the exception is declared in an inner
339 -- instance, nothing else to check.
341 elsif Is_Generic_Instance
(Scop
) then
345 Scop
:= Scope
(Scop
);
354 -- Check for redundant handler (has only raise statement) and is
355 -- either an others handler, or is a specific handler when no
356 -- others handler is present.
358 if Warn_On_Redundant_Constructs
359 and then List_Length
(Statements
(Handler
)) = 1
360 and then Nkind
(First
(Statements
(Handler
))) = N_Raise_Statement
361 and then No
(Name
(First
(Statements
(Handler
))))
362 and then (not Others_Present
363 or else Nkind
(First
(Exception_Choices
(Handler
))) =
367 ("useless handler contains only a reraise statement?r?",
371 -- Now analyze the statements of this handler
373 Analyze_Statements
(Statements
(Handler
));
375 -- If a choice was present, we created a special scope for it, so
376 -- this is where we pop that special scope to get rid of it.
378 if Present
(Choice
) then
385 end Analyze_Exception_Handlers
;
387 --------------------------------
388 -- Analyze_Handled_Statements --
389 --------------------------------
391 procedure Analyze_Handled_Statements
(N
: Node_Id
) is
392 Handlers
: constant List_Id
:= Exception_Handlers
(N
);
397 if Present
(Handlers
) then
401 -- We are now going to analyze the statements and then the exception
402 -- handlers. We certainly need to do things in this order to get the
403 -- proper sequential semantics for various warnings.
405 -- However, there is a glitch. When we process raise statements, an
406 -- optimization is to look for local handlers and specialize the code
409 -- In order to detect if a handler is matching, we must have at least
410 -- analyzed the choices in the proper scope so that proper visibility
411 -- analysis is performed. Hence we analyze just the choices first,
412 -- before we analyze the statement sequence.
414 Handler
:= First_Non_Pragma
(Handlers
);
415 while Present
(Handler
) loop
416 Choice
:= First_Non_Pragma
(Exception_Choices
(Handler
));
417 while Present
(Choice
) loop
419 Next_Non_Pragma
(Choice
);
422 Next_Non_Pragma
(Handler
);
425 -- Analyze statements in sequence
427 Analyze_Statements
(Statements
(N
));
429 -- If the current scope is a subprogram, entry or task body or declare
430 -- block then this is the right place to check for hanging useless
431 -- assignments from the statement sequence.
433 if Is_Subprogram_Or_Entry
(Current_Scope
)
434 or else Ekind
(Current_Scope
) in E_Block | E_Task_Type
436 Warn_On_Useless_Assignments
(Current_Scope
);
439 -- Deal with handlers or AT END proc
441 if Present
(Handlers
) then
442 Analyze_Exception_Handlers
(Handlers
);
443 elsif Present
(At_End_Proc
(N
)) then
444 Analyze
(At_End_Proc
(N
));
446 end Analyze_Handled_Statements
;
448 ------------------------------
449 -- Analyze_Raise_Expression --
450 ------------------------------
452 procedure Analyze_Raise_Expression
(N
: Node_Id
) is
453 Exception_Id
: constant Node_Id
:= Name
(N
);
454 Exception_Name
: Entity_Id
:= Empty
;
457 -- Check exception restrictions on the original source
459 if Comes_From_Source
(N
) then
460 Check_Restriction
(No_Exceptions
, N
);
463 Analyze
(Exception_Id
);
465 if Is_Entity_Name
(Exception_Id
) then
466 Exception_Name
:= Entity
(Exception_Id
);
469 if No
(Exception_Name
)
470 or else Ekind
(Exception_Name
) /= E_Exception
473 ("exception name expected in raise statement", Exception_Id
);
475 Set_Is_Raised
(Exception_Name
);
478 -- Deal with RAISE WITH case
480 if Present
(Expression
(N
)) then
481 Analyze_And_Resolve
(Expression
(N
), Standard_String
);
484 -- Check obsolescent use of Numeric_Error
486 if Exception_Name
= Standard_Numeric_Error
then
487 Check_Restriction
(No_Obsolescent_Features
, Exception_Id
);
490 -- Kill last assignment indication
492 Kill_Current_Values
(Last_Assignment_Only
=> True);
494 -- Raise_Type is compatible with all other types so that the raise
495 -- expression is legal in any expression context. It will be eventually
496 -- replaced by the concrete type imposed by the context.
498 Set_Etype
(N
, Raise_Type
);
499 end Analyze_Raise_Expression
;
501 -----------------------------
502 -- Analyze_Raise_Statement --
503 -----------------------------
505 procedure Analyze_Raise_Statement
(N
: Node_Id
) is
506 Exception_Id
: constant Node_Id
:= Name
(N
);
507 Exception_Name
: Entity_Id
:= Empty
;
512 Check_Unreachable_Code
(N
);
514 -- Check exception restrictions on the original source
516 if Comes_From_Source
(N
) then
517 Check_Restriction
(No_Exceptions
, N
);
520 -- Check for useless assignment to OUT or IN OUT scalar preceding the
521 -- raise. Right now only look at assignment statements, could do more???
523 if Is_List_Member
(N
) then
531 -- Skip past null statements and pragmas
534 and then Nkind
(P
) in N_Null_Statement | N_Pragma
539 -- See if preceding statement is an assignment
541 if Present
(P
) and then Nkind
(P
) = N_Assignment_Statement
then
544 -- Give warning for assignment to by-copy formal
546 if Is_Entity_Name
(L
)
547 and then Is_Formal
(Entity
(L
))
548 and then Is_By_Copy_Type
(Etype
(L
))
549 and then not Is_Aliased
(Entity
(L
))
551 -- Do this only for parameters to the current subprogram.
552 -- This avoids some false positives for the nested case.
554 and then Nearest_Dynamic_Scope
(Current_Scope
) =
558 -- Don't give warning if we are covered by an exception
559 -- handler, since this may result in false positives, since
560 -- the handler may handle the exception and return normally.
562 -- First find the enclosing handled sequence of statements
563 -- (note, we could also look for a handler in an outer block
564 -- but currently we don't, and in that case we'll emit the
570 exit when Nkind
(Par
) = N_Handled_Sequence_Of_Statements
;
573 -- See if there is a handler, give message if not
575 if No
(Exception_Handlers
(Par
)) then
577 ("assignment to pass-by-copy formal "
578 & "may have no effect??", P
);
580 ("\RAISE statement may result in abnormal return "
581 & "(RM 6.4.1(17))??", P
);
590 if No
(Exception_Id
) then
592 while Nkind
(P
) not in
593 N_Exception_Handler | N_Subprogram_Body | N_Package_Body |
594 N_Task_Body | N_Entry_Body
599 if Nkind
(P
) /= N_Exception_Handler
then
601 ("reraise statement must appear directly in a handler", N
);
603 -- If a handler has a reraise, it cannot be the target of a local
604 -- raise (goto optimization is impossible), and if the no exception
605 -- propagation restriction is set, this is a violation.
608 Set_Local_Raise_Not_OK
(P
);
609 Check_Restriction
(No_Exception_Propagation
, N
);
612 -- Normal case with exception id present
615 Analyze
(Exception_Id
);
617 if Is_Entity_Name
(Exception_Id
) then
618 Exception_Name
:= Entity
(Exception_Id
);
621 if No
(Exception_Name
)
622 or else Ekind
(Exception_Name
) /= E_Exception
625 ("exception name expected in raise statement", Exception_Id
);
627 Set_Is_Raised
(Exception_Name
);
630 -- Deal with RAISE WITH case
632 if Present
(Expression
(N
)) then
633 Analyze_And_Resolve
(Expression
(N
), Standard_String
);
637 -- Check obsolescent use of Numeric_Error
639 if Exception_Name
= Standard_Numeric_Error
then
640 Check_Restriction
(No_Obsolescent_Features
, Exception_Id
);
643 -- Kill last assignment indication
645 Kill_Current_Values
(Last_Assignment_Only
=> True);
646 end Analyze_Raise_Statement
;
648 ----------------------------------
649 -- Analyze_Raise_When_Statement --
650 ----------------------------------
652 procedure Analyze_Raise_When_Statement
(N
: Node_Id
) is
654 -- Verify the condition is a Boolean expression
656 Analyze_And_Resolve
(Condition
(N
), Any_Boolean
);
657 Check_Unset_Reference
(Condition
(N
));
658 end Analyze_Raise_When_Statement
;
660 -----------------------------
661 -- Analyze_Raise_xxx_Error --
662 -----------------------------
664 -- Normally, the Etype is already set (when this node is used within
665 -- an expression, since it is copied from the node which it rewrites).
666 -- If this node is used in a statement context, then we set the type
667 -- Standard_Void_Type. This is used both by Gigi and by the front end
668 -- to distinguish the statement use and the subexpression use.
670 -- The only other required processing is to take care of the Condition
671 -- field if one is present.
673 procedure Analyze_Raise_xxx_Error
(N
: Node_Id
) is
675 function Same_Expression
(C1
, C2
: Node_Id
) return Boolean;
676 -- It often occurs that two identical raise statements are generated in
677 -- succession (for example when dynamic elaboration checks take place on
678 -- separate expressions in a call). If the two statements are identical
679 -- according to the simple criterion that follows, the raise is
680 -- converted into a null statement.
682 ---------------------
683 -- Same_Expression --
684 ---------------------
686 function Same_Expression
(C1
, C2
: Node_Id
) return Boolean is
688 if No
(C1
) and then No
(C2
) then
691 elsif Is_Entity_Name
(C1
) and then Is_Entity_Name
(C2
) then
692 return Entity
(C1
) = Entity
(C2
);
694 elsif Nkind
(C1
) /= Nkind
(C2
) then
697 elsif Nkind
(C1
) in N_Unary_Op
then
698 return Same_Expression
(Right_Opnd
(C1
), Right_Opnd
(C2
));
700 elsif Nkind
(C1
) in N_Binary_Op
then
701 return Same_Expression
(Left_Opnd
(C1
), Left_Opnd
(C2
))
703 Same_Expression
(Right_Opnd
(C1
), Right_Opnd
(C2
));
705 elsif Nkind
(C1
) = N_Null
then
713 -- Start of processing for Analyze_Raise_xxx_Error
716 if No
(Etype
(N
)) then
717 Set_Etype
(N
, Standard_Void_Type
);
720 if Present
(Condition
(N
)) then
721 Analyze_And_Resolve
(Condition
(N
), Standard_Boolean
);
724 -- Deal with static cases in obvious manner
726 if Nkind
(Condition
(N
)) = N_Identifier
then
727 if Entity
(Condition
(N
)) = Standard_True
then
728 Set_Condition
(N
, Empty
);
730 elsif Entity
(Condition
(N
)) = Standard_False
then
731 Rewrite
(N
, Make_Null_Statement
(Sloc
(N
)));
735 -- Remove duplicate raise statements. Note that the previous one may
736 -- already have been removed as well.
738 if not Comes_From_Source
(N
)
739 and then Nkind
(N
) /= N_Null_Statement
740 and then Is_List_Member
(N
)
741 and then Present
(Prev
(N
))
742 and then Nkind
(N
) = Nkind
(Original_Node
(Prev
(N
)))
743 and then Same_Expression
744 (Condition
(N
), Condition
(Original_Node
(Prev
(N
))))
746 Rewrite
(N
, Make_Null_Statement
(Sloc
(N
)));
748 end Analyze_Raise_xxx_Error
;