===================================================================
@@ -5048,6 +5048,23 @@
effect of warning on unreferenced entities other than subprogram
formals.
+@item -gnatw.f
+@emph{Activate warnings on suspicious subprogram 'Access.}
+@cindex @option{-gnatw.f} (@command{gcc})
+This switch causes a warning to be generated if @code{P'Access} occurs
+in the same package where subprogram P is declared, and the
+@code{P'Access} is evaluated at elaboration time, and occurs before
+the body of P has been elaborated. For example, if we have
+@code{X : T := P'Access;}, then if X.all is subsequently called before
+the body of P is elaborated, it could cause
+access-before-elaboration. The default is that these warnings are not
+generated.
+
+@item -gnatw.F
+@emph{Suppress warnings on suspicious subprogram 'Access.}
+@cindex @option{-gnatw.F} (@command{gcc})
+This switch suppresses warnings for suspicious subprogram 'Access.
+
@item -gnatwg
@emph{Activate warnings on unrecognized pragmas.}
@cindex @option{-gnatwg} (@command{gcc})
===================================================================
@@ -326,6 +326,12 @@
when 'e' =>
All_Warnings (True);
+ when 'f' =>
+ Warn_On_Elab_Access := True;
+
+ when 'F' =>
+ Warn_On_Elab_Access := False;
+
when 'g' =>
Set_GNAT_Mode_Warnings;
===================================================================
@@ -1990,10 +1990,21 @@
Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;
begin
- -- If not function or procedure call or instantiation, then ignore
- -- call (this happens in some error cases and rewriting cases).
+ -- For P'Access, we want to warn if the -gnatw.f switch is set, and the
+ -- node comes from source.
- if not Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement)
+ if Nkind (N) = N_Attribute_Reference and then
+ (not Warn_On_Elab_Access or else not Comes_From_Source (N))
+ then
+ return;
+
+ -- If not function or procedure call, instantiation, or 'Access, then
+ -- ignore call (this happens in some error cases and rewriting cases).
+
+ elsif not Nkind_In
+ (N, N_Function_Call,
+ N_Procedure_Call_Statement,
+ N_Attribute_Reference)
and then not Inst_Case
then
return;
@@ -2001,7 +2012,7 @@
-- Nothing to do if this is a call or instantiation that has already
-- been found to be a sure ABE.
- elsif ABE_Is_Certain (N) then
+ elsif Nkind (N) /= N_Attribute_Reference and then ABE_Is_Certain (N) then
return;
-- Nothing to do if errors already detected (avoid cascaded errors)
@@ -2323,7 +2334,7 @@
-- Not that special case, warning and dynamic check is required
-- If we have nothing in the call stack, then this is at the outer
- -- level, and the ABE is bound to occur.
+ -- level, and the ABE is bound to occur, unless it's a 'Access.
if Elab_Call.Last = 0 then
Error_Msg_Warn := SPARK_Mode /= On;
@@ -2331,13 +2342,19 @@
if Inst_Case then
Error_Msg_NE
("cannot instantiate& before body seen<<", N, Orig_Ent);
+ elsif Nkind (N) /= N_Attribute_Reference then
+ Error_Msg_NE
+ ("cannot call& before body seen<<", N, Orig_Ent);
else
Error_Msg_NE
- ("cannot call& before body seen<<", N, Orig_Ent);
+ ("Access attribute of & before body seen<<", N, Orig_Ent);
+ Error_Msg_N ("\possible Program_Error on later references<", N);
end if;
- Error_Msg_N ("\Program_Error [<<", N);
- Insert_Elab_Check (N);
+ if Nkind (N) /= N_Attribute_Reference then
+ Error_Msg_N ("\Program_Error [<<", N);
+ Insert_Elab_Check (N);
+ end if;
-- Call is not at outer level
===================================================================
@@ -1669,6 +1669,13 @@
-- Set to True to generate warnings for suspicious use of export or
-- import pragmas. Modified by use of -gnatwx/X.
+ Warn_On_Elab_Access : Boolean := False;
+ -- GNAT
+ -- Set to True to generate warnings for P'Access in the case where
+ -- subprogram P is in the same package as the P'Access, and the P'Access is
+ -- evaluated at package elaboration time, and occurs before the body of P
+ -- has been elaborated.
+
Warn_On_Hiding : Boolean := False;
-- GNAT
-- Set to True to generate warnings if a declared entity hides another