This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] add warning


Tested on i686-linux, committed on trunk

This patch adds a warning for renaming a function return object,
as shown in this test, run with -gnatwa (the new warning is
under control of -gnatw.r which is included in -gnatwa).

     1. procedure xx is
     2.    G : integer := 0;
     3.    function yy return integer is
     4.    begin
     5.       G := G + 1;
     6.       return G;
     7.    end yy;
     8.    f : integer renames yy;
                               |
        >>> warning: renaming function result object is suspicious
        >>> warning: function "yy" will be called only once
        >>> warning: suggest using an initialized constant object instead

     9. begin
    10.    if f + f + f + f /= 4 then
    11.       raise Program_Error;
    12.    end if;
    13. end;

In this example, it would be more usual to do

f : integer := yy;

means the same thing, but much clearer.

This patch also makes GCC_Version private, to avoid compiler code
introducing direct tests on this value. The only remaining use
is in parametrizing static dispatch table handling, which is now
controlled by the deferred constant Static_Dispatch_Tables.

Some other obsolete references to GCC_Version have been removed.

This change is also needed to help some back-ends (e.g. .NET) determine whether
to use arithmetic instructions with overflow checks or not.

The code that verifies the legality of a library unit renaming must use the
flag Is_Compilation_Unit, rather than checking whether the scope of the unit
is Standard, so that Standard itself (which has no enclosing scope) can be
renamed as a library unit.

The following must compile quietly:

package Std renames Standard;

The RM description of Discard_Names says "within" the scope of the
pragma, but within in RM-speak includes inner scopes, and the code
was not propagating the flag to inner scopes. The one line patch to
sem_ch8.adb fixes this.

Note that this was originally reported as a failure of the pragma
Discard_Names in System.Restrictions (s-restri.ads) to operate
correctly (names were not suppressed), and this patch will fix
that specific problem.

The following is a test program:

package k is
   generic package p is
      type pt is (a, b, c);
   end p;

   type e1 is (d, e, f);
   pragma Discard_Names;

   type e2 is (g, h, i);

   package p1 is new p;

   package p2 is
      type e3 is (j, k, l);
   end p2;
end k;

When this test program is compiled, the only enumeration name
table not suppressed should be e1, but before this patch, pt
and e3 were also not suppressed. The easiest way to verify
correct compilation is to compile with -gnatG and search the
output for the string "constant string". The output should
be a single line:

   k__e1S : constant string (1 .. 3) := "DEF";

This patch improves the infinite loop warning, catching more cases (in
particular cases of nested function calls and comparisons of function
calls with constants), while at the same time decreasing false positives.
The latter is achieved by special casing suspicious names that suggest
file or network I/O, and mistrusting procedure calls on the grounds that
they may have some hidden side effect.

     1. procedure p is
     2.    x : Integer := 10;
     3.
     4.    procedure get (A : integer) is
     5.    begin
     6.       null;
     7.    end;
     8.
     9.    function Ident (X : Integer) return Integer is
    10.    begin
    11.       return X;
    12.    end;
    13.
    14.    function f (A : Integer) return Boolean;
    15.    pragma Warnings (Off, f);
    16.    function f (A : Integer) return Boolean is
    17.    begin
    18.       X := X + 1;
    19.       return X + A < 20;
    20.    end f;
    21.
    22.    function f0 (A : Integer) return Boolean;
    23.    function f0 (A : Integer) return Boolean is
    24.    begin
    25.       X := X + 1;
    26.       return X + A < 20;
    27.    end f0;
    28.
    29.    package io_elements is
    30.       function f2 (A : Integer) return Boolean;
    31.    end io_elements;
    32.
    33.    package body io_elements is
    34.       function f2 (A : Integer) return Boolean is
    35.       begin
    36.          return A > 3;
    37.       end f2;
    38.    end;
    39.
    40.    function f3_file_stuff (A : Integer) return Boolean is
    41.    begin
    42.       return A > 3;
    43.    end f3_file_stuff;
    44.
    45.    function f4_filestuff (A : Integer) return Boolean is
    46.     begin
    47.       return A > 3;
    48.    end f4_filestuff;
    49.
    50. begin
    51.    while f (X) loop                          -- no warn
    52.       null;
    53.    end loop;
    54.
    55.    while f0 (X) loop                         -- warn
                     |
        >>> warning: variable "x" may not be modified in loop body
        >>> warning: possible infinite loop

    56.       null;
    57.    end loop;
    58.
    59.    while f0 (Ident (Ident (X))) loop         -- warn
                                   |
        >>> warning: variable "x" may not be modified in loop body
        >>> warning: possible infinite loop

    60.       null;
    61.    end loop;
    62.
    63.   while io_elements.f2 (x) loop              -- no warn
    64.       null;
    65.    end loop;
    66.
    67.    while f3_file_stuff (x) = true loop       -- no warn
    68.       null;
    69.    end loop;
    70.
    71.    while f4_filestuff (x) = true loop        -- warn
                               |
        >>> warning: variable "x" may not be modified in loop body
        >>> warning: possible infinite loop

    72.       null;
    73.    end loop;
    74.
    75.    while f4_filestuff (x) = true loop        -- no warn
    76.       get (x);
    77.    end loop;
    78.
    79.    while f4_filestuff (x) = true loop        -- no warn
    80.       get (ident(x));
    81.    end loop;
    82. end;

2007-06-06  Robert Dewar  <dewar@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>

	* g-comlin.ads, g-comlin.adb: 
	Add new warning for renaming of function return objects

	* opt.adb (Tree_Write, Tree_Read): Use proper expressions for size
	(Tree_Read): Use size of object instead of type'object_size, since the
	latter is incorrect for packed array types.
	(Tree_Write): Same fix

	* opt.ads: Add new warning for renaming of function return objects
	(Generating_Code): New boolean variable used to indicate that the
	frontend as finished its work and has called the backend to process
	the tree and generate the object file.
	(GCC_Version): Is now private
	(Static_Dispatch_Tables): New constant declaration.
	(Overflow_Checks_Unsuppressed): New flag.
	(Process_Suppress_Unsuppress): Set Overflow_Checks_Unsuppressed.
	(List_Closure): New flag for gnatbind (-R)
	Zero_Formatting: New flag for gnatbind (-Z)
	(Special_Exception_Package_Used): New flag.
	(Warn_On_Unrepped_Components): New flag.

	* sem_ch8.adb (Check_Library_Unit_Renaming): Check that the renamed
	unit is a compilation unit, rather than relying on its scope, so that
	Standard can be renamed.
	(Analyze_Object_Renaming): Add new warning for renaming of function
	return objects.
	Also reject attempt to rename function return object in Ada 83 mode.
	(Attribute_Renaming): In case of tagged types, add the body of the
	generated function to the freezing actions of the type.
	(Find_Type): A protected type is visible right after the reserved word
	"is" is encountered in its type declaration. Set the entity and type
	rather than emitting an error message.
	(New_Scope): Properly propagate Discard_Names to inner scopes
	(Check_Nested_Access): New procedure.
	(Has_Nested_Access, Set_Has_Nested_Access): New procedures.
	(Find_Direct_Name, Note_Possible_Modification): Use Check_Nested_Access.

	* sem_warn.ads, sem_warn.adb: Improvements to infinite loop warning
	Add new warning for renaming of function return objects
	(Check_References): Suppress warnings for objects whose type or
	base type has Warnings suppressed.
	(Set_Dot_Warning_Switch): Add processing for -gnatw.c/C
	(Set_Warning_Switch): Include new -gnatwc in -gnatwa

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]