[Ada] Warning needed on anonymous access type allocators
authorJustin Squirek <squirek@adacore.com>
Tue, 9 Jul 2019 07:55:22 +0000 (07:55 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 9 Jul 2019 07:55:22 +0000 (07:55 +0000)
This patch enhances the compiler to add an optional warning for
allocators of anonymous access types due to the somewhat confusing
runtime accessibility checks that they generate. For more details see RM
3.10.2 sections 14/3, 14.1/3, and 14.2/3.

These warnings can now be enabled with -gnatw_a, disabled with -gnatw_A
and are part of the "all warnings" flag -gnatwa.

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

--  main.adb

procedure Main is

   type Int_Ptr is access all Integer;

   Ptr_Obj          :          Int_Ptr;
   Ptr_Not_Null_Obj : not null Int_Ptr := new Integer;
   Ptr_Anon_Acc_Obj : not null access Integer :=
     new Integer;                     --  WARNING

   procedure Update_Ptr (Item : access Integer) is
   begin
      Ptr_Obj := Int_Ptr (Item);      --  RUNTIME ERROR
   end;

   procedure Update_Ptr_With_Anonymous_Allocator is
      Item : access Integer := new Integer;
   begin
      Update_Ptr (Item);
   end;

   type Rec_With_Coextension_A (Disc : access Integer)
     is null record;

   type Rec_With_Coextension_B (Disc : access Integer) is record
      Comp : Integer;
   end record;

   Obj : Rec_With_Coextension_A :=
     (Disc => new Integer'(32));      -- WARNING

   procedure Test_Param (Param : access Integer) is
   begin
      null;
   end;

   function Test_Simple_Return return access Integer is
   begin
      return new Integer;             --  WARNING
   end;

   function Test_Coextension_Return_A return Rec_With_Coextension_A is
   begin
      return (Disc => new Integer);   --  WARNING
   end;

   function Test_Coextension_Return_B return Rec_With_Coextension_B is
   begin
      return (new Integer, 32);       --  WARNING
   end;

begin
   Test_Param (new Integer);          --  WARNING
   Test_Param (Param => new Integer); --  WARNING
   Update_Ptr_With_Anonymous_Allocator;
end;

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

$ gnatmake -q -gnatw_a main.adb
$ rm *.ali
$ gnatmake -q -gnatwa -gnatw_A main.adb
$ rm *.ali
$ gnatmake -q -gnatwa main.adb
$ main
main.adb:8:06: warning: use of an anonymous access type allocator
main.adb:16:32: warning: use of an anonymous access type allocator
main.adb:29:15: warning: use of an anonymous access type allocator
main.adb:38:14: warning: use of an anonymous access type allocator
main.adb:43:23: warning: coextension will not be deallocated when
its associated owner is deallocated
main.adb:43:23: warning: use of an anonymous access type allocator
main.adb:48:15: warning: coextension will not be deallocated when
its associated owner is deallocated
main.adb:48:15: warning: use of an anonymous access type allocator
main.adb:52:16: warning: use of an anonymous access type allocator
main.adb:53:25: warning: use of an anonymous access type allocator
main.adb:5:04: warning: variable "Ptr_Obj" is assigned but never read
main.adb:6:04: warning: variable "Ptr_Not_Null_Obj" is not referenced
main.adb:7:04: warning: variable "Ptr_Anon_Acc_Obj" is not referenced
main.adb:16:07: warning: "Item" is not modified, could be declared constant
main.adb:28:04: warning: variable "Obj" is not referenced
main.adb:36:13: warning: function "Test_Simple_Return" is not referenced
main.adb:41:13: warning: function "Test_Coextension_Return_A" is not referenced
main.adb:43:23: warning: coextension will not be deallocated when its
associated owner is deallocated
main.adb:46:13: warning: function "Test_Coextension_Return_B" is not referenced
main.adb:48:15: warning: coextension will not be deallocated when its
associated owner is deallocated
main.adb:5:04: warning: variable "Ptr_Obj" is assigned but never read
main.adb:6:04: warning: variable "Ptr_Not_Null_Obj" is not referenced
main.adb:7:04: warning: variable "Ptr_Anon_Acc_Obj" is not referenced
main.adb:8:06: warning: use of an anonymous access type allocator
main.adb:16:07: warning: "Item" is not modified, could be declared constant
main.adb:16:32: warning: use of an anonymous access type allocator
main.adb:28:04: warning: variable "Obj" is not referenced
main.adb:29:15: warning: use of an anonymous access type allocator
main.adb:36:13: warning: function "Test_Simple_Return" is not referenced
main.adb:38:14: warning: use of an anonymous access type allocator
main.adb:41:13: warning: function "Test_Coextension_Return_A" is not referenced
main.adb:43:23: warning: coextension will not be deallocated when its
associated owner is deallocated
main.adb:43:23: warning: use of an anonymous access type allocator
main.adb:46:13: warning: function "Test_Coextension_Return_B" is not referenced
main.adb:48:15: warning: coextension will not be deallocated when its
associated owner is deallocated
main.adb:48:15: warning: use of an anonymous access type allocator
main.adb:52:16: warning: use of an anonymous access type allocator
main.adb:53:25: warning: use of an anonymous access type allocator

raised PROGRAM_ERROR : main.adb:12 accessibility check failed

2019-07-09  Justin Squirek  <squirek@adacore.com>

gcc/ada/

* exp_ch4.adb (Expand_N_Allocator): Add conditional to detect
the presence of anoymous access type allocators and issue a
warning if the appropriate warning flag is enabled.
* warnsw.ads: Add new warning flag for anonymous allocators
* warnsw.adb (All_Warnings, Restore_Warnings, Save_Warnings,
Set_Underscore_Warning_Switch): Register new flags.
(WA_Warnings): Register new flag as an "all warnings" switch
* usage.adb,
doc/gnat_ugn/building_executable_programs_with_gnat.rst:
Document new warning switches -gnatw_a and -gnatw_A.
* gnat_ugn.texi: Regenerate.

From-SVN: r273290

gcc/ada/ChangeLog
gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
gcc/ada/exp_ch4.adb
gcc/ada/gnat_ugn.texi
gcc/ada/usage.adb
gcc/ada/warnsw.adb
gcc/ada/warnsw.ads

index 1dd2a38e12f3b1505bc46171bab52ee026349e32..ee00d1f4b993b2f545c1ddb638bee2ba4e85e11d 100644 (file)
@@ -1,3 +1,17 @@
+2019-07-09  Justin Squirek  <squirek@adacore.com>
+
+       * exp_ch4.adb (Expand_N_Allocator): Add conditional to detect
+       the presence of anoymous access type allocators and issue a
+       warning if the appropriate warning flag is enabled.
+       * warnsw.ads: Add new warning flag for anonymous allocators
+       * warnsw.adb (All_Warnings, Restore_Warnings, Save_Warnings,
+       Set_Underscore_Warning_Switch): Register new flags.
+       (WA_Warnings): Register new flag as an "all warnings" switch
+       * usage.adb,
+       doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+       Document new warning switches -gnatw_a and -gnatw_A.
+       * gnat_ugn.texi: Regenerate.
+
 2019-07-09  Ed Schonberg  <schonberg@adacore.com>
 
        * sem_ch4.adb (Diagnose_Call): Improve error recovery when a
index 98c3e165ba251d9520d793f813fcfbc26615f13b..af8f8a4492b60db93fb2af3400884033d03678ad 100644 (file)
@@ -2842,6 +2842,29 @@ of the pragma in the :title:`GNAT_Reference_manual`).
   compile time that the assertion will fail.
 
 
+.. index:: -gnatw_a
+
+:switch:`-gnatw_a`
+  *Activate warnings on anonymous allocators.*
+
+  .. index:: Anonymous allocators
+
+  This switch activates warnings for allocators of anonymous access types,
+  which can involve run-time accessibility checks and lead to unexpected
+  accessibility violations. For more details on the rules involved, see
+  RM 3.10.2 (14).
+
+
+.. index:: -gnatw_A
+
+:switch:`-gnatw_A`
+  *Supress warnings on anonymous allocators.*
+
+  .. index:: Anonymous allocators
+
+  This switch suppresses warnings for anonymous access type allocators.
+
+
 .. index:: -gnatwb  (gcc)
 
 :switch:`-gnatwb`
index 99bde93e18625a43d022bfebfcad7ba2d73ba915..b4159a7cefc83263e8799c5bce31cf0106f0b7c8 100644 (file)
@@ -72,6 +72,7 @@ with Ttypes;   use Ttypes;
 with Uintp;    use Uintp;
 with Urealp;   use Urealp;
 with Validsw;  use Validsw;
+with Warnsw;   use Warnsw;
 
 package body Exp_Ch4 is
 
@@ -4354,6 +4355,15 @@ package body Exp_Ch4 is
    --  Start of processing for Expand_N_Allocator
 
    begin
+      --  Warn on the presence of an allocator of an anonymous access type when
+      --  enabled.
+
+      if Warn_On_Anonymous_Allocators
+        and then Ekind (PtrT) = E_Anonymous_Access_Type
+      then
+         Error_Msg_N ("?use of an anonymous access type allocator", N);
+      end if;
+
       --  RM E.2.3(22). We enforce that the expected type of an allocator
       --  shall not be a remote access-to-class-wide-limited-private type
 
index 124c289c86665a3fcb60b7a2e46d0db534107b0e..db2adafcc1a956ecfdc359f8d5ca4e92cb002060 100644 (file)
@@ -11040,6 +11040,37 @@ This switch suppresses warnings for assertions where the compiler can tell at
 compile time that the assertion will fail.
 @end table
 
+@geindex -gnatw_a
+
+
+@table @asis
+
+@item @code{-gnatw_a}
+
+@emph{Activate warnings on anonymous allocators.}
+
+@geindex Anonymous allocators
+
+This switch activates warnings for allocators of anonymous access types,
+which can involve run-time accessibility checks and lead to unexpected
+accessibility violations. For more details on the rules involved, see
+RM 3.10.2 (14).
+@end table
+
+@geindex -gnatw_A
+
+
+@table @asis
+
+@item @code{-gnatw_A}
+
+@emph{Supress warnings on anonymous allocators.}
+
+@geindex Anonymous allocators
+
+This switch suppresses warnings for anonymous access type allocators.
+@end table
+
 @geindex -gnatwb (gcc)
 
 
index 1eace056a48cbf0e399f87925a5d901157ef978f..fb261e5fbc0b9b4e24ef7102626f9b450600a0f5 100644 (file)
@@ -483,6 +483,8 @@ begin
    Write_Line ("        A    turn off all optional info/warnings");
    Write_Line ("        .a*+ turn on warnings for failing assertion");
    Write_Line ("        .A   turn off warnings for failing assertion");
+   Write_Line ("        _a*+ turn on warnings for anonymous allocators");
+   Write_Line ("        _A   turn off warnings for anonymous allocators");
    Write_Line ("        b+   turn on warnings for bad fixed value " &
                                                   "(not multiple of small)");
    Write_Line ("        B*   turn off warnings for bad fixed value " &
index 472f1dff9dca640d822b52f289487f2749cc51a3..219d440bc87a49e1a60153e37dbcb869955e2deb 100644 (file)
@@ -56,6 +56,7 @@ package body Warnsw is
       Warn_On_Ada_2005_Compatibility      := Setting;
       Warn_On_Ada_2012_Compatibility      := Setting;
       Warn_On_All_Unread_Out_Parameters   := Setting;
+      Warn_On_Anonymous_Allocators        := Setting;
       Warn_On_Assertion_Failure           := Setting;
       Warn_On_Assumed_Low_Bound           := Setting;
       Warn_On_Atomic_Synchronization      := Setting;
@@ -129,6 +130,8 @@ package body Warnsw is
         W.Warn_On_Ada_2012_Compatibility;
       Warn_On_All_Unread_Out_Parameters   :=
         W.Warn_On_All_Unread_Out_Parameters;
+      Warn_On_Anonymous_Allocators        :=
+        W.Warn_On_Anonymous_Allocators;
       Warn_On_Assertion_Failure           :=
         W.Warn_On_Assertion_Failure;
       Warn_On_Assumed_Low_Bound           :=
@@ -235,6 +238,8 @@ package body Warnsw is
         Warn_On_Ada_2012_Compatibility;
       W.Warn_On_All_Unread_Out_Parameters   :=
         Warn_On_All_Unread_Out_Parameters;
+      W.Warn_On_Anonymous_Allocators        :=
+        Warn_On_Anonymous_Allocators;
       W.Warn_On_Assertion_Failure           :=
         Warn_On_Assertion_Failure;
       W.Warn_On_Assumed_Low_Bound           :=
@@ -478,6 +483,12 @@ package body Warnsw is
    function Set_Underscore_Warning_Switch (C : Character) return Boolean is
    begin
       case C is
+         when 'a' =>
+            Warn_On_Anonymous_Allocators := True;
+
+         when 'A' =>
+            Warn_On_Anonymous_Allocators := False;
+
          when others =>
             if Ignore_Unrecognized_VWY_Switches then
                Write_Line ("unrecognized switch -gnatw_" & C & " ignored");
@@ -705,6 +716,7 @@ package body Warnsw is
       Ineffective_Inline_Warnings         := True; -- -gnatwp
       Warn_On_Ada_2005_Compatibility      := True; -- -gnatwy
       Warn_On_Ada_2012_Compatibility      := True; -- -gnatwy
+      Warn_On_Anonymous_Allocators        := True; -- -gnatw_a
       Warn_On_Assertion_Failure           := True; -- -gnatw.a
       Warn_On_Assumed_Low_Bound           := True; -- -gnatww
       Warn_On_Bad_Fixed_Value             := True; -- -gnatwb
index 23970a9d56f43347ae4066c4cfcf16d83648f34d..5875ecd0525f7886aea4f49a87d4c5b2e54063f4 100644 (file)
@@ -38,6 +38,12 @@ package Warnsw is
    --  here as time goes by. And in fact a really nice idea would be to put
    --  them all in a Warn_Record so that they would be easy to save/restore.
 
+   Warn_On_Anonymous_Allocators : Boolean := False;
+   --  Warn when allocators for anonymous access types are present, which,
+   --  although not illegal in Ada, may be confusing to users due to how
+   --  accessibility checks get generated. Off by default, modified by use of
+   --  -gnatw_a/_A and set as part of -gnatwa.
+
    Warn_On_Late_Primitives : Boolean := False;
    --  Warn when tagged type public primitives are defined after its private
    --  extensions.
@@ -90,6 +96,7 @@ package Warnsw is
       Warn_On_Ada_2005_Compatibility      : Boolean;
       Warn_On_Ada_2012_Compatibility      : Boolean;
       Warn_On_All_Unread_Out_Parameters   : Boolean;
+      Warn_On_Anonymous_Allocators        : Boolean;
       Warn_On_Assertion_Failure           : Boolean;
       Warn_On_Assumed_Low_Bound           : Boolean;
       Warn_On_Atomic_Synchronization      : Boolean;