This patch improves the error recovery when WHEN is used in place of WITH for aspect specifications:
1. package WhenWith is 2. X : integer when Size => 4; | >>> "when" should be "with" 3. Y : integer when Rubbish; | >>> missing ";" 4. procedure Q when Inline; | >>> barrier not allowed on procedure, only on entry 5. end WhenWith; Tested on x86_64-pc-linux-gnu, committed on trunk 2015-02-05 Robert Dewar <de...@adacore.com> * par-ch13.adb (With_Present): New function (Aspect_Specifications_Present): Handle WHEN in place of WITH (Get_Aspect_Specifications): Comment update. * par.adb: Comment updates.
Index: par-ch13.adb =================================================================== --- par-ch13.adb (revision 220439) +++ par-ch13.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2015, 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- -- @@ -48,6 +48,10 @@ function Possible_Misspelled_Aspect return Boolean; -- Returns True, if Token_Name is a misspelling of some aspect name + function With_Present return Boolean; + -- Returns True if WITH is present, indicating presence of aspect + -- specifications. Also allows incorrect use of WHEN in place of WITH. + -------------------------------- -- Possible_Misspelled_Aspect -- -------------------------------- @@ -63,6 +67,43 @@ return False; end Possible_Misspelled_Aspect; + ------------------ + -- With_Present -- + ------------------ + + function With_Present return Boolean is + begin + if Token = Tok_With then + return True; + + -- Check for WHEN used in place of WITH + + elsif Token = Tok_When then + declare + Scan_State : Saved_Scan_State; + + begin + Save_Scan_State (Scan_State); + Scan; -- past WHEN + + if Token = Tok_Identifier + and then Get_Aspect_Id (Token_Name) /= No_Aspect + then + Error_Msg_SC ("WHEN should be WITH"); + Restore_Scan_State (Scan_State); + return True; + + else + Restore_Scan_State (Scan_State); + return False; + end if; + end; + + else + return False; + end if; + end With_Present; + -- Start of processing for Aspect_Specifications_Present begin @@ -79,14 +120,15 @@ -- be too expensive. Instead we pick up the aspect specifications later -- as a bogus declaration, and diagnose the semicolon at that point. - if Token /= Tok_With then + if not With_Present then return False; end if; - -- Have a WITH, see if it looks like an aspect specification + -- Have a WITH or some token that we accept as a legitimate bad attempt + -- at writing WITH. See if it looks like an aspect specification Save_Scan_State (Scan_State); - Scan; -- past WITH + Scan; -- past WITH (or WHEN or other bad keyword) -- If no identifier, then consider that we definitely do not have an -- aspect specification. @@ -193,7 +235,7 @@ return Aspects; end if; - Scan; -- past WITH + Scan; -- past WITH (or possible WHEN after error) Aspects := Empty_List; -- Loop to scan aspects Index: par.adb =================================================================== --- par.adb (revision 220439) +++ par.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2015, 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- -- @@ -951,6 +951,9 @@ -- permitted). Note: this routine never checks the terminator token -- for aspects so it does not matter whether the aspect specifications -- are terminated by semicolon or some other character. + -- + -- Note: This function also handles the case of WHEN used where WITH + -- was intended, and in that case posts an error and returns True. procedure P_Aspect_Specifications (Decl : Node_Id; @@ -960,15 +963,17 @@ -- argument is False, the scan pointer is left pointing past the aspects -- and the caller must check for a proper terminator. -- - -- P_Aspect_Specifications is called with the current token pointing to - -- either a WITH keyword starting an aspect specification, or an - -- instance of the terminator token. In the former case, the aspect - -- specifications are scanned out including the terminator token if it - -- it is a semicolon, and the Has_Aspect_Specifications flag is set in - -- the given declaration node. A list of aspects is built and stored for - -- this declaration node using a call to Set_Aspect_Specifications. If - -- no WITH keyword is present, then this call has no effect other than - -- scanning out the terminator if it is a semicolon. + -- P_Aspect_Specifications is called with the current token pointing + -- to either a WITH keyword starting an aspect specification, or an + -- instance of what shpould be a terminator token. In the former case, + -- the aspect specifications are scanned out including the terminator + -- token if it it is a semicolon, and the Has_Aspect_Specifications + -- flag is set in the given declaration node. A list of aspects + -- is built and stored for this declaration node using a call to + -- Set_Aspect_Specifications. If no WITH keyword is present, then this + -- call has no effect other than scanning out the terminator if it is a + -- semicolon (with the exception that it detects WHEN used in place of + -- WITH). -- If Decl is Error on entry, any scanned aspect specifications are -- ignored and a message is output saying aspect specifications not