This patch adds the switch (-gnateinn, MAX_INSTANTIATIONS=nn in VMS)
to control the maximum number of instantiations. This may be used to
increase the limit from the default of 8000 in the very rare case
where a single unit legitimately has more than 8000 instantiations.

The following program:

     1. procedure MaxInst is
     2.    generic package P is
     3.       X : Integer;
     4.    end;
     5.
     6.    package P1 is new P;
     7.    package P2 is new P;
     8.    package P4 is new P;
     9.    package P5 is new P;
    10.    package P6 is new P;
    11.    package P7 is new P;
    12.    package P8 is new P;
    13.    package P9 is new P;
    14. begin
    15.    null;
    16. end;

If compiled with -gnatei4 -gnatj64, yields

maxinst.adb:12:04: too many instantiations, exceeds max of 4,
                   limit can be changed using -gnateinn switch
compilation abandoned

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-03-15  Robert Dewar  <de...@adacore.com>

        * errout.ads: Add entry for translating -gnateinn to
        /MAX_INSTANTIATIONS for VMS.
        * hostparm.ads (Max_Instantiations): Moved to Opt.
        * opt.ads (Maximum_Instantiations): Moved from Hostparm, and renamed.
        * sem_ch12.adb (Maximum_Instantiations): New name of
        Max_Instantiations (Analyze_Package_Instantiation): Change error
        msg for too many instantiations (mention -gnateinn switch).
        * switch-c.adb (Scan_Front_End_Switches): Implement -gnateinn switch.
        * switch.ads: Minor comment update.
        * usage.adb (Usage): Output line for -maxeinn switch.
        * vms_data.ads: Add entry for MAX_INSTANTIATIONS (-gnateinn).

Index: switch-c.adb
===================================================================
--- switch-c.adb        (revision 185390)
+++ switch-c.adb        (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 2001-2012, 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- --
@@ -482,6 +482,13 @@
                      Generate_Processed_File := True;
                      Ptr := Ptr + 1;
 
+                  --  -gnatei (max number of instantiations)
+
+                  when 'i' =>
+                     Ptr := Ptr + 1;
+                     Scan_Pos
+                       (Switch_Chars, Max, Ptr, Maximum_Instantiations, C);
+
                   --  -gnateI (index of unit in multi-unit source)
 
                   when 'I' =>
Index: usage.adb
===================================================================
--- usage.adb   (revision 185390)
+++ usage.adb   (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                B o d y                                   --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -197,6 +197,11 @@
    Write_Switch_Char ("eG");
    Write_Line ("Generate preprocessed source");
 
+   --  Line for -gnatei switch
+
+   Write_Switch_Char ("einn");
+   Write_Line ("Set maximumum number of instantiations to nn");
+
    --  Line for -gnateI switch
 
    Write_Switch_Char ("eInn");
Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb        (revision 185417)
+++ sem_ch12.adb        (working copy)
@@ -34,7 +34,6 @@
 with Fname;    use Fname;
 with Fname.UF; use Fname.UF;
 with Freeze;   use Freeze;
-with Hostparm;
 with Itypes;   use Itypes;
 with Lib;      use Lib;
 with Lib.Load; use Lib.Load;
@@ -3784,8 +3783,10 @@
             --  Here is a defence against a ludicrous number of instantiations
             --  caused by a circular set of instantiation attempts.
 
-            if Pending_Instantiations.Last > Hostparm.Max_Instantiations then
-               Error_Msg_N ("too many instantiations", N);
+            if Pending_Instantiations.Last > Maximum_Instantiations then
+               Error_Msg_Uint_1 := UI_From_Int (Maximum_Instantiations);
+               Error_Msg_N ("too many instantiations, exceeds max of^", N);
+               Error_Msg_N ("\limit can be changed using -gnateinn switch", N);
                raise Unrecoverable_Error;
             end if;
 
Index: errout.ads
===================================================================
--- errout.ads  (revision 185390)
+++ errout.ads  (working copy)
@@ -380,6 +380,9 @@
    Gname8 : aliased constant String := "gnat2012";
    Vname8 : aliased constant String := "2012";
 
+   Gname9 : aliased constant String := "gnateinn";
+   Vname9 : aliased constant String := "MAX_INSTANTIATIONS=nn";
+
    type Cstring_Ptr is access constant String;
 
    Gnames : array (Nat range <>) of Cstring_Ptr :=
@@ -390,7 +393,8 @@
                Gname5'Access,
                Gname6'Access,
                Gname7'Access,
-               Gname8'Access);
+               Gname8'Access,
+               Gname9'Access);
 
    Vnames : array (Nat range <>) of Cstring_Ptr :=
               (Vname1'Access,
@@ -400,7 +404,8 @@
                Vname5'Access,
                Vname6'Access,
                Vname7'Access,
-               Vname8'Access);
+               Vname8'Access,
+               Vname9'Access);
 
    -----------------------------------------------------
    -- Global Values Used for Error Message Insertions --
Index: vms_data.ads
===================================================================
--- vms_data.ads        (revision 185390)
+++ vms_data.ads        (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1996-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1996-2012, 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- --
@@ -1926,11 +1926,14 @@
    --   When using a project file, GNAT MAKE creates a temporary mapping file
    --   and communicates it to the compiler using this switch.
 
-   S_GCC_Multi   : aliased constant S := "/MULTI_UNIT_INDEX=#"             &
-                                            "-gnateI#";
-   --        /MULTI_UNIT_INDEX=nnn
+   S_GCC_MaxI    : aliased constant S := "/MAX_INSTANTIATIONS=#"           &
+                                            "-gnatei#";
+
+   --        /MAX_INSTANTIATIONS=nnn
    --
-   --   Specify the index of the unit to compile in a multi-unit source file.
+   --   Specify the maximum number of instantiations permitted. The default
+   --   value is 8000, which is probably enough for all programs except those
+   --   containing some kind of runaway unintended instantiation loop.
 
    S_GCC_Mess    : aliased constant S := "/MESSAGES_PROJECT_FILE="         &
                                             "DEFAULT "                     &
@@ -1951,6 +1954,12 @@
    --      HIGH        A great number of messages are output, most of them not
    --                  being useful for the user.
 
+   S_GCC_Multi   : aliased constant S := "/MULTI_UNIT_INDEX=#"             &
+                                            "-gnateI#";
+   --        /MULTI_UNIT_INDEX=nnn
+   --
+   --   Specify the index of the unit to compile in a multi-unit source file.
+
    S_GCC_Nesting  : aliased constant S := "/MAX_NESTING=#"                 &
                                              "-gnatyL#";
    --        /MAX_NESTING=nnn
@@ -3585,6 +3594,7 @@
                      S_GCC_Output  'Access,
                      S_GCC_Machine 'Access,
                      S_GCC_Mapping 'Access,
+                     S_GCC_MaxI    'Access,
                      S_GCC_Multi   'Access,
                      S_GCC_Mess    'Access,
                      S_GCC_Nesting 'Access,
Index: opt.ads
===================================================================
--- opt.ads     (revision 185390)
+++ opt.ads     (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -931,6 +931,12 @@
    --  extension, as set by the appropriate switch. If no switch is given,
    --  then this value is initialized by Osint to the appropriate value.
 
+   Maximum_Instantiations : Int := 8000;
+   --  GNAT
+   --  Maximum number of instantiations permitted (to stop runaway cases
+   --  of nested instantiations). These situations probably only occur in
+   --  specially concocted test cases. Can be modified by -gnateinn switch.
+
    Maximum_Processes : Positive := 1;
    --  GNATMAKE, GPRMAKE, GPRBUILD
    --  Maximum number of processes that should be spawned to carry out
@@ -940,12 +946,6 @@
    --  GNATMAKE
    --  Set to True if minimal recompilation mode requested
 
-   Special_Exception_Package_Used : Boolean := False;
-   --  GNAT
-   --  Set to True if either of the unit GNAT.Most_Recent_Exception or
-   --  GNAT.Exception_Traces is with'ed. Used to inhibit transformation of
-   --  local raise statements into gotos in the presence of either package.
-
    Multiple_Unit_Index : Int;
    --  GNAT
    --  This is set non-zero if the current unit is being compiled in multiple
@@ -1182,6 +1182,12 @@
    --  GNAT
    --  Set True if a pragma Short_Descriptors applies to the current unit.
 
+   Special_Exception_Package_Used : Boolean := False;
+   --  GNAT
+   --  Set to True if either of the unit GNAT.Most_Recent_Exception or
+   --  GNAT.Exception_Traces is with'ed. Used to inhibit transformation of
+   --  local raise statements into gotos in the presence of either package.
+
    Sprint_Line_Limit : Nat := 72;
    --  GNAT
    --  Limit values for chopping long lines in Sprint output, can be reset
Index: hostparm.ads
===================================================================
--- hostparm.ads        (revision 185390)
+++ hostparm.ads        (working copy)
@@ -69,11 +69,6 @@
    --  of file names in the library, must be at least Max_Line_Length, but
    --  can be larger.
 
-   Max_Instantiations : constant := 8000;
-   --  Maximum number of instantiations permitted (to stop runaway cases
-   --  of nested instantiations). These situations probably only occur in
-   --  specially concocted test cases.
-
    Tag_Errors : constant Boolean := False;
    --  If set to true, then brief form error messages will be prefaced by
    --  the string "error:". Used as default for Opt.Unique_Error_Tag.
Index: switch.ads
===================================================================
--- switch.ads  (revision 185390)
+++ switch.ads  (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -123,9 +123,8 @@
       Ptr          : in out Integer;
       Result       : out Pos;
       Switch       : Character);
-   --  Scan positive integer parameter for switch. On entry, Ptr points just
-   --  past the switch character, on exit it points past the last digit of the
-   --  integer value.
+   --  Scan positive integer parameter for switch. Identical to Scan_Nat with
+   --  same parameters except that zero is considered out of range.
 
    procedure Bad_Switch (Switch : Character);
    procedure Bad_Switch (Switch : String);

Reply via email to