This patch implements additional warnings for suspicious mod values as shown by the following test program. These warnings are under control of the warning flag -gnatw.m (on by default).
1. package susmod is 2. type r is mod 2 * 32; | >>> warning: suspicious "mod" value, was ** intended? 3. H : Integer := 2458; 4. J : Integer := H mod 2 * 32; | >>> warning: suspicious "mod" value, was ** intended? 5. end susmod; Tested on x86_64-pc-linux-gnu, committed on trunk 2012-01-30 Robert Dewar <de...@adacore.com> * sem.adb (Analyze): Call Analyze_Mod for N_Op_Mod mode. * sem_ch3.adb (Modular_Type_Declaration): Warn on mod value of form 2 * small-literal. * sem_ch4.adb (Analyze_Mod): New procedure (warn on suspicious mod value). * sem_ch4.ads (Analyze_Mod): New procedure.
Index: sem_ch3.adb =================================================================== --- sem_ch3.adb (revision 183704) +++ sem_ch3.adb (working copy) @@ -16808,6 +16808,21 @@ -- Start of processing for Modular_Type_Declaration begin + -- If the mod expression is (exactly) 2 * literal, where literal is + -- 64 or less,then almost certainly the * was meant to be **. Warn! + + if Warn_On_Suspicious_Modulus_Value + and then Nkind (Mod_Expr) = N_Op_Multiply + and then Nkind (Left_Opnd (Mod_Expr)) = N_Integer_Literal + and then Intval (Left_Opnd (Mod_Expr)) = Uint_2 + and then Nkind (Right_Opnd (Mod_Expr)) = N_Integer_Literal + and then Intval (Right_Opnd (Mod_Expr)) <= Uint_64 + then + Error_Msg_N ("suspicious MOD value, was '*'* intended'??", Mod_Expr); + end if; + + -- Proceed with analysis of mod expression + Analyze_And_Resolve (Mod_Expr, Any_Integer); Set_Etype (T, T); Set_Ekind (T, E_Modular_Integer_Type); Index: sem.adb =================================================================== --- sem.adb (revision 183694) +++ sem.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- -- @@ -376,7 +376,7 @@ Analyze_Unary_Op (N); when N_Op_Mod => - Analyze_Arithmetic_Op (N); + Analyze_Mod (N); when N_Op_Multiply => Analyze_Arithmetic_Op (N); Index: sem_ch4.adb =================================================================== --- sem_ch4.adb (revision 183694) +++ sem_ch4.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- -- @@ -62,6 +62,7 @@ with Sinfo; use Sinfo; with Snames; use Snames; with Tbuild; use Tbuild; +with Uintp; use Uintp; package body Sem_Ch4 is @@ -2637,6 +2638,34 @@ end if; end Analyze_Membership_Op; + ----------------- + -- Analyze_Mod -- + ----------------- + + procedure Analyze_Mod (N : Node_Id) is + begin + -- A special warning check, if we have an expression of the form: + -- expr mod 2 * literal + -- where literal is 64 or less, then probably what was meant was + -- expr mod 2 ** literal + -- so issue an appropriate warning. + + if Warn_On_Suspicious_Modulus_Value + and then Nkind (Right_Opnd (N)) = N_Integer_Literal + and then Intval (Right_Opnd (N)) = Uint_2 + and then Nkind (Parent (N)) = N_Op_Multiply + and then Nkind (Right_Opnd (Parent (N))) = N_Integer_Literal + and then Intval (Right_Opnd (Parent (N))) <= Uint_64 + then + Error_Msg_N + ("suspicious MOD value, was '*'* intended'??", Parent (N)); + end if; + + -- Remaining processing is same as for other arithmetic operators + + Analyze_Arithmetic_Op (N); + end Analyze_Mod; + ---------------------- -- Analyze_Negation -- ---------------------- Index: sem_ch4.ads =================================================================== --- sem_ch4.ads (revision 183694) +++ sem_ch4.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- -- @@ -39,6 +39,7 @@ procedure Analyze_Expression_With_Actions (N : Node_Id); procedure Analyze_Logical_Op (N : Node_Id); procedure Analyze_Membership_Op (N : Node_Id); + procedure Analyze_Mod (N : Node_Id); procedure Analyze_Negation (N : Node_Id); procedure Analyze_Null (N : Node_Id); procedure Analyze_Qualified_Expression (N : Node_Id);