[Ada] another gnatprep fix

Arnaud Charlet charlet@adacore.com
Fri Jun 15 08:29:00 GMT 2007


Tested on i686-linux, committed on trunk

The behavior of "#if not X or Y then" was not clearly described and
different from the Ada semantic. For Ada, it is equivalent to
"if (not X) or Y then", while for preprocessing it was equivalent to
"if not (X or Y) then". This patch forbids "not" followed by "or"
or "and" without parentheses.
The test for this is to preprocess a source with a line such as
   #if X or Y then
Preprocessing should fail.

2007-06-06  Vincent Celier  <celier@adacore.com>

	* prep.ads, prep.adb (Expression): New Boolean parameter Complemented,
	defaulted to False.
	In the "not" case, recursive call with Complemented set to True.
	Do not allow "or" or "and" operators when Complemented is True.

-------------- next part --------------
Index: prep.ads
===================================================================
--- prep.ads	(revision 124068)
+++ prep.ads	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 2002-2006, Free Software Foundation, Inc.         --
+--          Copyright (C) 2002-2007, 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- --
@@ -26,7 +26,8 @@
 
 with GNAT.Dynamic_Tables;
 
-with Types;  use Types;
+with Namet; use Namet;
+with Types; use Types;
 
 package Prep is
 
Index: prep.adb
===================================================================
--- prep.adb	(revision 124068)
+++ prep.adb	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2002-2006, Free Software Foundation, Inc.         --
+--          Copyright (C) 2002-2007, 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- --
@@ -26,7 +26,6 @@
 
 with Csets;    use Csets;
 with Err_Vars; use Err_Vars;
-with Namet;    use Namet;
 with Opt;      use Opt;
 with Osint;    use Osint;
 with Output;   use Output;
@@ -191,7 +190,9 @@ package body Prep is
    function Deleting return Boolean;
    --  Return True if code should be deleted or commented out
 
-   function Expression (Evaluate_It : Boolean) return Boolean;
+   function Expression
+     (Evaluate_It  : Boolean;
+      Complemented : Boolean := False) return Boolean;
    --  Evaluate a condition in an #if or an #elsif statement.
    --  If Evaluate_It is False, the condition is effectively evaluated,
    --  otherwise, only the syntax is checked.
@@ -361,7 +362,6 @@ package body Prep is
 
       if Pp_States.Last = Ground then
          return False;
-
       else
          return Pp_States.Table (Pp_States.Last).Deleting;
       end if;
@@ -371,7 +371,10 @@ package body Prep is
    -- Expression --
    ----------------
 
-   function Expression (Evaluate_It : Boolean) return Boolean is
+   function Expression
+     (Evaluate_It  : Boolean;
+      Complemented : Boolean := False) return Boolean
+   is
       Evaluation : Boolean := Evaluate_It;
       --  Is set to False after an "or else" when left term is True and
       --  after an "and then" when left term is False.
@@ -420,7 +423,8 @@ package body Prep is
                --  not expression
 
                Scan.all;
-               Current_Result := not Expression (Evaluation);
+               Current_Result :=
+                 not Expression (Evaluation, Complemented => True);
 
             when Tok_Identifier =>
                Symbol_Name1 := Token_Name;
@@ -601,7 +605,12 @@ package body Prep is
          --  Check the next operator
 
          if Token = Tok_And then
-            if Current_Operator = Op_Or then
+            if Complemented then
+               Error_Msg
+                ("mixing NOT and AND is not allowed, parentheses are required",
+                 Token_Ptr);
+
+            elsif Current_Operator = Op_Or then
                Error_Msg ("mixing OR and AND is not allowed", Token_Ptr);
             end if;
 
@@ -617,7 +626,12 @@ package body Prep is
             end if;
 
          elsif Token = Tok_Or then
-            if Current_Operator = Op_And then
+            if Complemented then
+               Error_Msg
+                 ("mixing NOT and OR is not allowed, parentheses are required",
+                  Token_Ptr);
+
+            elsif Current_Operator = Op_And then
                Error_Msg ("mixing AND and OR is not allowed", Token_Ptr);
             end if;
 


More information about the Gcc-patches mailing list