@@ -4706,7 +4706,7 @@ Style Checking
.. index:: -gnaty (gcc)
-The :switch:`-gnatyx` switch causes the compiler to
+The :switch:`-gnaty` switch causes the compiler to
enforce specified style rules. A limited set of style rules has been used
in writing the GNAT sources themselves. This switch allows user programs
to activate all or some of these checks. If the source program fails a
@@ -4904,9 +4904,9 @@ checks to be performed. The following checks are defined:
The set of style check switches is set to match that used by the GNAT sources.
This may be useful when developing code that is eventually intended to be
- incorporated into GNAT. Currently this is equivalent to :switch:`-gnatyydISux`)
- but additional style switches may be added to this set in the future without
- advance notice.
+ incorporated into GNAT. Currently this is equivalent to
+ :switch:`-gnatyydISuxz`) but additional style switches may be added to this
+ set in the future without advance notice.
.. index:: -gnatyh (gcc)
@@ -5207,9 +5207,9 @@ checks to be performed. The following checks are defined:
:switch:`-gnatyx`
*Check extra parentheses.*
- Unnecessary extra level of parentheses (C-style) are not allowed
- around conditions in ``if`` statements, ``while`` statements and
- ``exit`` statements.
+ Unnecessary extra levels of parentheses (C-style) are not allowed
+ around conditions (or selection expressions) in ``if``, ``while``,
+ ``case``, and ``exit`` statements, as well as part of ranges.
.. index:: -gnatyy (gcc)
@@ -5223,6 +5223,15 @@ checks to be performed. The following checks are defined:
:switch:`-gnatyS`, :switch:`-gnatyu`, and :switch:`-gnatyx`.
+.. index:: -gnatyz (gcc)
+
+:switch:`-gnatyz`
+ *Check extra parentheses (operator precedence).*
+
+ Extra levels of parentheses that are not required by operator precedence
+ rules are flagged. See also ``-gnatyx``.
+
+
.. index:: -gnaty- (gcc)
:switch:`-gnaty-`
@@ -13312,7 +13312,7 @@ temporary disabling of validity checks.
@geindex -gnaty (gcc)
-The @code{-gnatyx} switch causes the compiler to
+The @code{-gnaty} switch causes the compiler to
enforce specified style rules. A limited set of style rules has been used
in writing the GNAT sources themselves. This switch allows user programs
to activate all or some of these checks. If the source program fails a
@@ -13569,9 +13569,9 @@ in the source text.
The set of style check switches is set to match that used by the GNAT sources.
This may be useful when developing code that is eventually intended to be
-incorporated into GNAT. Currently this is equivalent to @code{-gnatyydISux})
-but additional style switches may be added to this set in the future without
-advance notice.
+incorporated into GNAT. Currently this is equivalent to
+@code{-gnatyydISuxz}) but additional style switches may be added to this
+set in the future without advance notice.
@end table
@geindex -gnatyh (gcc)
@@ -13965,9 +13965,9 @@ one blank line occurs in sequence.
`Check extra parentheses.'
-Unnecessary extra level of parentheses (C-style) are not allowed
-around conditions in @code{if} statements, @code{while} statements and
-@code{exit} statements.
+Unnecessary extra levels of parentheses (C-style) are not allowed
+around conditions (or selection expressions) in @code{if}, @code{while},
+@code{case}, and @code{exit} statements, as well as part of ranges.
@end table
@geindex -gnatyy (gcc)
@@ -13985,6 +13985,19 @@ options enabled with the exception of @code{-gnatyB}, @code{-gnatyd},
@code{-gnatyS}, @code{-gnatyu}, and @code{-gnatyx}.
@end table
+@geindex -gnatyz (gcc)
+
+
+@table @asis
+
+@item @code{-gnatyz}
+
+`Check extra parentheses (operator precedence).'
+
+Extra levels of parentheses that are not required by operator precedence
+rules are flagged. See also @code{-gnatyx}.
+@end table
+
@geindex -gnaty- (gcc)
@@ -874,7 +874,7 @@ package body System.Interrupts is
To_System (Interrupt_Access_Hold.all'Identity);
end if;
- if (New_Handler = null) and then Old_Handler /= null then
+ if New_Handler = null and then Old_Handler /= null then
-- Restore default handler
@@ -914,7 +914,7 @@ package body System.Interrupts is
To_System (Interrupt_Access_Hold.all'Identity);
end if;
- if (New_Handler = null) and then Old_Handler /= null then
+ if New_Handler = null and then Old_Handler /= null then
-- Restore default handler
@@ -979,7 +979,7 @@ package body System.Regpat is
C := Expression (Parse_Pos);
Parse_Pos := Parse_Pos + 1;
- case (C) is
+ case C is
when '^' =>
IP :=
Emit_Node
@@ -3074,7 +3074,12 @@ package body Ch3 is
Check_Simple_Expression (Expr_Node);
Set_High_Bound (Range_Node, Expr_Node);
- if Style_Check then
+ -- If Expr_Node (ignoring parentheses) is not a simple expression
+ -- then emit a style check.
+
+ if Style_Check
+ and then Nkind (Expr_Node) not in N_Op_Boolean | N_Subexpr
+ then
Style.Check_Xtra_Parens (Expr_Node);
end if;
@@ -1359,7 +1359,7 @@ package body Ch5 is
else
if Style_Check then
- Style.Check_Xtra_Parens (Cond, Enable => True);
+ Style.Check_Xtra_Parens (Cond);
end if;
-- And return the result
@@ -1384,6 +1384,7 @@ package body Ch5 is
function P_Case_Statement return Node_Id is
Case_Node : Node_Id;
+ Expr : Node_Id;
Alternatives_List : List_Id;
First_When_Loc : Source_Ptr;
@@ -1398,7 +1399,14 @@ package body Ch5 is
Scopes (Scope.Last).Node := Case_Node;
Scan; -- past CASE
- Set_Expression (Case_Node, P_Expression_No_Right_Paren);
+
+ Expr := P_Expression_No_Right_Paren;
+
+ if Style_Check then
+ Style.Check_Xtra_Parens (Expr);
+ end if;
+
+ Set_Expression (Case_Node, Expr);
TF_Is;
-- Prepare to parse case statement alternatives
@@ -3157,13 +3157,13 @@ package body Sem_Ch4 is
if Nkind (L) not in N_Short_Circuit | N_Op_And | N_Op_Or | N_Op_Xor
and then Is_Boolean_Type (Etype (L))
then
- Check_Xtra_Parens (L);
+ Check_Xtra_Parens_Precedence (L);
end if;
if Nkind (R) not in N_Short_Circuit | N_Op_And | N_Op_Or | N_Op_Xor
and then Is_Boolean_Type (Etype (R))
then
- Check_Xtra_Parens (R);
+ Check_Xtra_Parens_Precedence (R);
end if;
end if;
end Analyze_Logical_Op;
@@ -6042,12 +6042,12 @@ package body Sem_Ch4 is
if Style_Check then
if Nkind (L) not in N_Short_Circuit | N_Op_And | N_Op_Or | N_Op_Xor
then
- Check_Xtra_Parens (L);
+ Check_Xtra_Parens_Precedence (L);
end if;
if Nkind (R) not in N_Short_Circuit | N_Op_And | N_Op_Or | N_Op_Xor
then
- Check_Xtra_Parens (R);
+ Check_Xtra_Parens_Precedence (R);
end if;
end if;
end Analyze_Short_Circuit;
@@ -30068,7 +30068,7 @@ package body Sem_Prag is
| Name_Loop_Invariant
| Name_Loop_Variant)
then
- case (Chars (Get_Pragma_Arg (Last (PPA)))) is
+ case Chars (Get_Pragma_Arg (Last (PPA))) is
when Name_Check
| Name_On
=>
@@ -28,7 +28,6 @@
-- gathered in a separate package so that they can more easily be customized.
-- Calls to these subprograms are only made if Opt.Style_Check is set True.
-with Debug; use Debug;
with Errout;
with Styleg;
with Types; use Types;
@@ -193,10 +192,15 @@ package Style is
renames Style_Inst.Check_Vertical_Bar;
-- Called after scanning a vertical bar to check spacing
- procedure Check_Xtra_Parens (N : Node_Id; Enable : Boolean := Debug_Flag_QQ)
+ procedure Check_Xtra_Parens (N : Node_Id)
renames Style_Inst.Check_Xtra_Parens;
- -- Called after scanning an expression (N) that does not require an extra
- -- level of parentheses around the entire expression.
+ -- Called after scanning an entire expression (N) that does not require an
+ -- extra level of parentheses.
+
+ procedure Check_Xtra_Parens_Precedence (N : Node_Id)
+ renames Style_Inst.Check_Xtra_Parens_Precedence;
+ -- Called after scanning a subexpression (N) that does not require an
+ -- extra level of parentheses according to operator precedence rules.
function Mode_In_Check return Boolean
renames Style_Inst.Mode_In_Check;
@@ -1119,12 +1119,9 @@ package body Styleg is
-- Check_Xtra_Parens --
-----------------------
- procedure Check_Xtra_Parens (N : Node_Id; Enable : Boolean) is
+ procedure Check_Xtra_Parens (N : Node_Id) is
begin
- -- Do not emit messages about expressions that may require parentheses
-
if Style_Check_Xtra_Parens
- and then Enable
and then
Paren_Count (N) >
(if Nkind (N) in N_Case_Expression
@@ -1140,6 +1137,28 @@ package body Styleg is
end if;
end Check_Xtra_Parens;
+ ----------------------------------
+ -- Check_Xtra_Parens_Precedence --
+ ----------------------------------
+
+ procedure Check_Xtra_Parens_Precedence (N : Node_Id) is
+ begin
+ if Style_Check_Xtra_Parens_Precedence
+ and then
+ Paren_Count (N) >
+ (if Nkind (N) in N_Case_Expression
+ | N_Expression_With_Actions
+ | N_If_Expression
+ | N_Quantified_Expression
+ | N_Raise_Expression
+ then 1
+ else 0)
+ then
+ Error_Msg -- CODEFIX
+ ("(style) redundant parentheses?z?", Errout.First_Sloc (N));
+ end if;
+ end Check_Xtra_Parens_Precedence;
+
----------------------------
-- Determine_Token_Casing --
----------------------------
@@ -160,10 +160,13 @@ package Styleg is
procedure Check_Vertical_Bar;
-- Called after scanning a vertical bar to check spacing
- procedure Check_Xtra_Parens (N : Node_Id; Enable : Boolean);
- -- Called after scanning an expression (N) that does not require an extra
- -- level of parentheses around the entire expression.
- -- Enable is a temporary parameter before enabling these checks by default.
+ procedure Check_Xtra_Parens (N : Node_Id);
+ -- Called after scanning an entire expression (N) that does not require an
+ -- extra level of parentheses.
+
+ procedure Check_Xtra_Parens_Precedence (N : Node_Id);
+ -- Called after scanning a subexpression (N) that does not require an
+ -- extra level of parentheses according to operator precedence rules.
function Mode_In_Check return Boolean;
pragma Inline (Mode_In_Check);
@@ -58,12 +58,8 @@ package body Stylesw is
"I" & -- check mode IN
"S" & -- check separate lines after THEN or ELSE
"u" & -- check no unnecessary blank lines
- "x"; -- check extra parentheses around conditionals
-
- -- Note: we intend GNAT_Style to also include the following, but we do
- -- not yet have the whole tool suite clean with respect to this.
-
- -- "B" & -- check boolean operators
+ "x" & -- check extra parentheses around conditionals
+ "z"; -- check parens not required by precedence rules.
-------------------------------
-- Reset_Style_Check_Options --
@@ -71,33 +67,34 @@ package body Stylesw is
procedure Reset_Style_Check_Options is
begin
- Style_Check_Indentation := 0;
- Style_Check_Array_Attribute_Index := False;
- Style_Check_Attribute_Casing := False;
- Style_Check_Blanks_At_End := False;
- Style_Check_Blank_Lines := False;
- Style_Check_Boolean_And_Or := False;
- Style_Check_Comments := False;
- Style_Check_DOS_Line_Terminator := False;
- Style_Check_Mixed_Case_Decls := False;
- Style_Check_End_Labels := False;
- Style_Check_Form_Feeds := False;
- Style_Check_Horizontal_Tabs := False;
- Style_Check_If_Then_Layout := False;
- Style_Check_Keyword_Casing := False;
- Style_Check_Layout := False;
- Style_Check_Max_Line_Length := False;
- Style_Check_Max_Nesting_Level := False;
- Style_Check_Missing_Overriding := False;
- Style_Check_Mode_In := False;
- Style_Check_Order_Subprograms := False;
- Style_Check_Pragma_Casing := False;
- Style_Check_References := False;
- Style_Check_Separate_Stmt_Lines := False;
- Style_Check_Specs := False;
- Style_Check_Standard := False;
- Style_Check_Tokens := False;
- Style_Check_Xtra_Parens := False;
+ Style_Check_Indentation := 0;
+ Style_Check_Array_Attribute_Index := False;
+ Style_Check_Attribute_Casing := False;
+ Style_Check_Blanks_At_End := False;
+ Style_Check_Blank_Lines := False;
+ Style_Check_Boolean_And_Or := False;
+ Style_Check_Comments := False;
+ Style_Check_DOS_Line_Terminator := False;
+ Style_Check_Mixed_Case_Decls := False;
+ Style_Check_End_Labels := False;
+ Style_Check_Form_Feeds := False;
+ Style_Check_Horizontal_Tabs := False;
+ Style_Check_If_Then_Layout := False;
+ Style_Check_Keyword_Casing := False;
+ Style_Check_Layout := False;
+ Style_Check_Max_Line_Length := False;
+ Style_Check_Max_Nesting_Level := False;
+ Style_Check_Missing_Overriding := False;
+ Style_Check_Mode_In := False;
+ Style_Check_Order_Subprograms := False;
+ Style_Check_Pragma_Casing := False;
+ Style_Check_References := False;
+ Style_Check_Separate_Stmt_Lines := False;
+ Style_Check_Specs := False;
+ Style_Check_Standard := False;
+ Style_Check_Tokens := False;
+ Style_Check_Xtra_Parens := False;
+ Style_Check_Xtra_Parens_Precedence := False;
end Reset_Style_Check_Options;
---------------------
@@ -187,6 +184,7 @@ package body Stylesw is
Add ('t', Style_Check_Tokens);
Add ('u', Style_Check_Blank_Lines);
Add ('x', Style_Check_Xtra_Parens);
+ Add ('z', Style_Check_Xtra_Parens_Precedence);
if Style_Check_Max_Line_Length then
P := P + 1;
@@ -426,44 +424,47 @@ package body Stylesw is
or else Options (Err_Col) not in '0' .. '9';
end loop;
- Style_Check_Max_Line_Length := Style_Max_Line_Length /= 0;
+ Style_Check_Max_Line_Length := Style_Max_Line_Length /= 0;
when 'n' =>
- Style_Check_Standard := True;
+ Style_Check_Standard := True;
when 'N' =>
Reset_Style_Check_Options;
when 'o' =>
- Style_Check_Order_Subprograms := True;
+ Style_Check_Order_Subprograms := True;
when 'O' =>
- Style_Check_Missing_Overriding := True;
+ Style_Check_Missing_Overriding := True;
when 'p' =>
- Style_Check_Pragma_Casing := True;
+ Style_Check_Pragma_Casing := True;
when 'r' =>
- Style_Check_References := True;
+ Style_Check_References := True;
when 's' =>
- Style_Check_Specs := True;
+ Style_Check_Specs := True;
when 'S' =>
- Style_Check_Separate_Stmt_Lines := True;
+ Style_Check_Separate_Stmt_Lines := True;
when 't' =>
- Style_Check_Tokens := True;
+ Style_Check_Tokens := True;
when 'u' =>
- Style_Check_Blank_Lines := True;
+ Style_Check_Blank_Lines := True;
when 'x' =>
- Style_Check_Xtra_Parens := True;
+ Style_Check_Xtra_Parens := True;
when 'y' =>
Set_Default_Style_Check_Options;
+ when 'z' =>
+ Style_Check_Xtra_Parens_Precedence := True;
+
when ' ' =>
null;
@@ -491,89 +492,92 @@ package body Stylesw is
Style_Check_Indentation := 0;
when 'a' =>
- Style_Check_Attribute_Casing := False;
+ Style_Check_Attribute_Casing := False;
when 'A' =>
- Style_Check_Array_Attribute_Index := False;
+ Style_Check_Array_Attribute_Index := False;
when 'b' =>
- Style_Check_Blanks_At_End := False;
+ Style_Check_Blanks_At_End := False;
when 'B' =>
- Style_Check_Boolean_And_Or := False;
+ Style_Check_Boolean_And_Or := False;
when 'c' | 'C' =>
- Style_Check_Comments := False;
+ Style_Check_Comments := False;
when 'd' =>
- Style_Check_DOS_Line_Terminator := False;
+ Style_Check_DOS_Line_Terminator := False;
when 'D' =>
- Style_Check_Mixed_Case_Decls := False;
+ Style_Check_Mixed_Case_Decls := False;
when 'e' =>
- Style_Check_End_Labels := False;
+ Style_Check_End_Labels := False;
when 'f' =>
- Style_Check_Form_Feeds := False;
+ Style_Check_Form_Feeds := False;
when 'g' =>
Reset_Style_Check_Options;
when 'h' =>
- Style_Check_Horizontal_Tabs := False;
+ Style_Check_Horizontal_Tabs := False;
when 'i' =>
- Style_Check_If_Then_Layout := False;
+ Style_Check_If_Then_Layout := False;
when 'I' =>
- Style_Check_Mode_In := False;
+ Style_Check_Mode_In := False;
when 'k' =>
- Style_Check_Keyword_Casing := False;
+ Style_Check_Keyword_Casing := False;
when 'l' =>
- Style_Check_Layout := False;
+ Style_Check_Layout := False;
when 'L' =>
Style_Max_Nesting_Level := 0;
when 'm' =>
- Style_Check_Max_Line_Length := False;
+ Style_Check_Max_Line_Length := False;
when 'M' =>
- Style_Max_Line_Length := 0;
- Style_Check_Max_Line_Length := False;
+ Style_Max_Line_Length := 0;
+ Style_Check_Max_Line_Length := False;
when 'n' =>
- Style_Check_Standard := False;
+ Style_Check_Standard := False;
when 'o' =>
- Style_Check_Order_Subprograms := False;
+ Style_Check_Order_Subprograms := False;
when 'O' =>
- Style_Check_Missing_Overriding := False;
+ Style_Check_Missing_Overriding := False;
when 'p' =>
- Style_Check_Pragma_Casing := False;
+ Style_Check_Pragma_Casing := False;
when 'r' =>
- Style_Check_References := False;
+ Style_Check_References := False;
when 's' =>
- Style_Check_Specs := False;
+ Style_Check_Specs := False;
when 'S' =>
- Style_Check_Separate_Stmt_Lines := False;
+ Style_Check_Separate_Stmt_Lines := False;
when 't' =>
- Style_Check_Tokens := False;
+ Style_Check_Tokens := False;
when 'u' =>
- Style_Check_Blank_Lines := False;
+ Style_Check_Blank_Lines := False;
when 'x' =>
- Style_Check_Xtra_Parens := False;
+ Style_Check_Xtra_Parens := False;
+
+ when 'z' =>
+ Style_Check_Xtra_Parens_Precedence := False;
when ' ' =>
null;
@@ -279,6 +279,11 @@ package Stylesw is
-- not allowed to enclose entire expressions in tests in parentheses
-- (C style), e.g. if (x = y) then ... is not allowed.
+ Style_Check_Xtra_Parens_Precedence : Boolean := False;
+ -- This can be set True by using the -gnatyz switch. If true, then it is
+ -- not allowed to enclose subexpressions in parentheses when not required
+ -- by operator precedence rules, e.g. (X > 1) and (Y < 1).
+
Style_Max_Line_Length : Nat := 0;
-- Value used to check maximum line length. Gets reset as a result of
-- use of -gnatym or -gnatyMnnn switches. This value is only read if
@@ -683,6 +683,8 @@ begin
Write_Line (" u check no unnecessary blank lines");
Write_Line (" x check extra parentheses around conditionals");
Write_Line (" y turn on default style checks");
+ Write_Line (" z check parentheses not required by operator " &
+ "precedence rules");
Write_Line (" - subtract (turn off) subsequent checks");
Write_Line (" + add (turn on) subsequent checks");
From: Arnaud Charlet <charlet@adacore.com> Improve -gnatyx to check additional complete conditions, and introduce a new switch -gnatyz to check for unnecessary parentheses according to operator precedence rules. Enable -gnatyz as part of -gnatyg. gcc/ada/ * par-ch5.adb, style.ads, styleg.adb, styleg.ads (Check_Xtra_Parens): Remove extra parameter Enable. (Check_Xtra_Parens_Precedence): New. (P_Case_Statement): Add -gnatyx style check. * sem_ch4.adb: Replace calls to Check_Xtra_Parens by Check_Xtra_Parens_Precedence. * stylesw.ads, stylesw.adb, usage.adb: Add support for -gnatyz. * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Update -gnatyxzg doc. * sem_prag.adb, libgnat/s-regpat.adb, libgnarl/s-interr__hwint.adb, libgnarl/s-interr__vxworks.adb: Remove extra parens. * par-ch3.adb (P_Discrete_Range): Do not emit a style check if the expression is not a simple expression. * gnat_ugn.texi: Regenerate. Tested on x86_64-pc-linux-gnu, committed on master. --- ...building_executable_programs_with_gnat.rst | 23 ++- gcc/ada/gnat_ugn.texi | 27 +++- gcc/ada/libgnarl/s-interr__hwint.adb | 2 +- gcc/ada/libgnarl/s-interr__vxworks.adb | 2 +- gcc/ada/libgnat/s-regpat.adb | 2 +- gcc/ada/par-ch3.adb | 7 +- gcc/ada/par-ch5.adb | 12 +- gcc/ada/sem_ch4.adb | 8 +- gcc/ada/sem_prag.adb | 2 +- gcc/ada/style.ads | 12 +- gcc/ada/styleg.adb | 27 +++- gcc/ada/styleg.ads | 11 +- gcc/ada/stylesw.adb | 146 +++++++++--------- gcc/ada/stylesw.ads | 5 + gcc/ada/usage.adb | 2 + 15 files changed, 180 insertions(+), 108 deletions(-)