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] new warnings


Tested on i686-linux, committed on trunk.

This patch introduces a new warning for some cases of while loops
which look like infinite loops. The case detected is a simple test
of a local variable, where the local variable is not modified in
the loop. Like most warnings, one can imagine a case where the
warning is inaccurate (e.g. an exception takes you out of the
loop), but in practice this seems a very useful warning that
catches many common cases with no false positives.

The following program:

procedure p is
   X : Integer;
   B : Boolean;
   X2 : Integer;
   pragma Warnings (Off, X2);

   function T (X : Integer) return Boolean is
   begin
      return X > 3;
   end T;

begin
   while X > 3 loop
      B := True;
   end loop;

   while X2 > 3 loop
      B := True;
   end loop;

   while B loop
      X := X + 1;
   end loop;

   while T (X) loop
      B := False;
   end loop;

   while X > 3 loop
      X := X + 1;
   end loop;

   while X > 3 loop
      p;
   end loop;

   while X > 3 loop
      B := T (X);
   end loop;
end;

Generates when compiled with -gnatld7


Compiling: p.adb

     1. procedure p is
     2.    X : Integer;
     3.    B : Boolean;
     4.    X2 : Integer;
     5.    pragma Warnings (Off, X2);
     6.
     7.    function T (X : Integer) return Boolean is
     8.    begin
     9.       return X > 3;
    10.    end T;
    11.
    12. begin
    13.    while X > 3 loop
                 |
        >>> warning: variable "X" is not modified in loop body
        >>> warning: possible infinite loop
        >>> warning: "X" may be referenced before it has a value

    14.       B := True;
    15.    end loop;
    16.
    17.    while X2 > 3 loop
    18.       B := True;
    19.    end loop;
    20.
    21.    while B loop
                 |
        >>> warning: variable "B" is not modified in loop body
        >>> warning: possible infinite loop

    22.       X := X + 1;
    23.    end loop;
    24.
    25.    while T (X) loop
                    |
        >>> warning: variable "X" is not modified in loop body
        >>> warning: possible infinite loop

    26.       B := False;
    27.    end loop;
    28.
    29.    while X > 3 loop
    30.       X := X + 1;
    31.    end loop;
    32.
    33.    while X > 3 loop
                 |
        >>> warning: variable "X" is not modified in loop body
        >>> warning: possible infinite loop

    34.       p;
    35.    end loop;
    36.
    37.    while X > 3 loop
    38.       B := T (X);
    39.    end loop;
    40. end;

 40 lines: No errors, 9 warnings

The bounds of a loop in a generic may resolve to a non-generic type and
be constant-folded into literals. When we analyze the loop in the instance
we must preserve the user-defined type for consistency with other uses of
the loop variable within subsequent code.
See gnat.dg/loop_bound.adb

Finally, this corrects an obvious small oversight of insisting on identifiers
for current value tracking, and not allowing qualified names.

The following program compiled with -gnatwa

procedure b is
    X : Integer;
begin
    if B.X = 3 then
       null;
       if B.X = 3 then
          null;
       end if;
    end if;
end;

should generate the warnings:

b.adb:2:05: warning: variable "X" is read but never assigned
b.adb:6:15: warning: condition is always True

The second warning is new with this patch

2006-10-31  Robert Dewar  <dewar@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>
	    Gary Dismukes  <dismukes@adacore.com>

	* sem_ch5.ads, sem_ch5.adb (Analyze_Loop_Statement): Add circuit to
	warn on infinite loops.
	Add \\ to some continuation messages
	(Analyze_Assignment_Statement): Call Warn_On_Useless_Assignment
	(Process_Bounds): If the bounds are integer literals that result from
	constant-folding, and they carry a user-defined type, preserve that type
	rather than treating this as an integer range.
	(Analyze_Exit_Statement): Test for E_Return_Statement in legality check.
	(Analyze_Goto_Statement): Test for E_Return_Stateemnt in legality check.
	(Analyze_Assignment_Statement): Add call to Check_Elab_Assign for
	left hand side of assignment.
	(Analyze_Assignment): Add suport to manage assigments to the attribute
	priority of a protected object.
	(Check_Possible_Current_Value_Condition): Allow fully qualified names
	not just identifiers.
	(Check_Possible_Current_Value_Condition): Acquire left operand of AND
	or AND THEN for possible tracking.
	(Analyze_Iteration_Scheme): Check for setting Current_Value for the
	case of while loops so we can track values in the loop body.

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]