Prevent mispelling error messages with internal attribute names CPU, Dispatching_Domain and Interrupt_Priority.
For example: ------------ -- Source -- ------------ pragma Ada_2012; procedure P is X : Integer; for X'CPU use 3; -- unrecognized attribute (internal to GNAT) for X'CPUX use 3; -- unrecognized attribute (and not a mispelling of CPU) begin if X'CPU = 3 then -- unrecognized attribute null; end if; end P; ----------------- -- Compilation -- ----------------- gnatmake -q p.adb --------------------- -- Expected output -- --------------------- p.adb:4:10: unrecognized attribute "CPU" p.adb:5:10: unrecognized attribute "CPUX" p.adb:7:09: unrecognized attribute "CPU" gnatmake: "p.adb" compilation error Tested on x86_64-pc-linux-gnu, committed on trunk 2012-07-09 Vincent Pucci <pu...@adacore.com> * exp_attr.adb (Signal_Bad_Attribute): Raise Program_Error in case of internal attribute names (already rejected by the parser). * par-ch13.adb (P_Representation_Clause): Complain if an internal attribute name that comes from source occurs. * par-ch4.adb (P_Name): Complain if an internal attribute name occurs in the context of an attribute reference. * par-util.adb (Signal_Bad_Attribute): Don't complain about mispelling attribute with internal attributes. * sem_attr.adb (Analyze_Attribute): Raise Program_Error in case of internal attribute names (already rejected by the parser). * snames.adb-tmpl (Is_Internal_Attribute_Name): New routine. * snames.ads-tmpl: Attributes CPU, Dispatching_Domain and Interrupt_Priority are marked as INT attributes since they don't denote real attribute and are only used internally in the compiler. (Is_Internal_Attribute_Name): New routine.
Index: exp_attr.adb =================================================================== --- exp_attr.adb (revision 189367) +++ exp_attr.adb (working copy) @@ -835,13 +835,16 @@ Attribute_Default_Iterator | Attribute_Implicit_Dereference | Attribute_Iterator_Element | - Attribute_Variable_Indexing => null; + Attribute_Variable_Indexing => + null; - -- Attributes related to Ada 2012 aspects + -- Internal attributes used to deal with Ada 2012 delayed aspects + -- (already diagnosed by parser, thus nothing more to do here). when Attribute_CPU | Attribute_Dispatching_Domain | - Attribute_Interrupt_Priority => null; + Attribute_Interrupt_Priority => + raise Program_Error; ------------ -- Access -- Index: par-ch13.adb =================================================================== --- par-ch13.adb (revision 189366) +++ par-ch13.adb (working copy) @@ -221,7 +221,14 @@ if Token = Tok_Identifier then Attr_Name := Token_Name; - if not Is_Attribute_Name (Attr_Name) then + -- Note that the parser must complain in case of an internal + -- attribute names that comes from source since internal names + -- are meant to be used only by the compiler. + + if not Is_Attribute_Name (Attr_Name) + or else (Is_Internal_Attribute_Name (Attr_Name) + and then Comes_From_Source (Token_Node)) + then Signal_Bad_Attribute; end if; Index: par-ch4.adb =================================================================== --- par-ch4.adb (revision 189366) +++ par-ch4.adb (working copy) @@ -434,7 +434,12 @@ elsif Token = Tok_Identifier then Attr_Name := Token_Name; - if not Is_Attribute_Name (Attr_Name) then + -- Note that internal attributes names don't denote real + -- attribute. + + if not Is_Attribute_Name (Attr_Name) + or else Is_Internal_Attribute_Name (Attr_Name) + then if Apostrophe_Should_Be_Semicolon then Expr_Form := EF_Name; return Name_Node; Index: sem_attr.adb =================================================================== --- sem_attr.adb (revision 189376) +++ sem_attr.adb (working copy) @@ -2215,13 +2215,13 @@ Attribute_Variable_Indexing => Error_Msg_N ("illegal attribute", N); - -- Attributes related to Ada 2012 aspects. Attribute definition clause - -- exists for these, but they cannot be queried. + -- Internal attributes used to deal with Ada 2012 delayed aspects + -- (already diagnosed by parser, thus nothing more to do here). when Attribute_CPU | Attribute_Dispatching_Domain | Attribute_Interrupt_Priority => - Error_Msg_N ("illegal attribute", N); + raise Program_Error; ------------------ -- Abort_Signal -- Index: snames.adb-tmpl =================================================================== --- snames.adb-tmpl (revision 189366) +++ snames.adb-tmpl (working copy) @@ -392,6 +392,17 @@ or else N not in Ada_2012_Reserved_Words); end Is_Keyword_Name; + -------------------------------- + -- Is_Internal_Attribute_Name -- + -------------------------------- + + function Is_Internal_Attribute_Name (N : Name_Id) return Boolean is + begin + return N = Name_CPU + or N = Name_Interrupt_Priority + or N = Name_Dispatching_Domain; + end Is_Internal_Attribute_Name; + ---------------------------- -- Is_Locking_Policy_Name -- ---------------------------- Index: par-util.adb =================================================================== --- par-util.adb (revision 189366) +++ par-util.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- -- @@ -721,7 +721,12 @@ Error_Msg_Name_1 := First_Attribute_Name; while Error_Msg_Name_1 <= Last_Attribute_Name loop - if Is_Bad_Spelling_Of (Token_Name, Error_Msg_Name_1) then + -- No mispelling possible with internal attribute names since they + -- don't denote real attribute. + + if not Is_Internal_Attribute_Name (Error_Msg_Name_1) + and then Is_Bad_Spelling_Of (Token_Name, Error_Msg_Name_1) + then Error_Msg_N -- CODEFIX ("\possible misspelling of %", Token_Node); exit; Index: snames.ads-tmpl =================================================================== --- snames.ads-tmpl (revision 189366) +++ snames.ads-tmpl (working copy) @@ -753,6 +753,11 @@ -- implementation dependent attributes may be found in the appropriate -- section in Sem_Attr. + -- The entries marked INT are not real attributes. They are special names + -- used internally by GNAT in order to deal with delayed aspects + -- (Aspect_CPU, Aspect_Dispatching_Domain, Aspect_Interrupt_Priority) that + -- don't have corresponding pragma or attribute. + -- The entries marked VMS are recognized only in OpenVMS implementations -- of GNAT, and are treated as illegal in all other contexts. @@ -779,7 +784,7 @@ Name_Constant_Indexing : constant Name_Id := N + $; -- GNAT Name_Constrained : constant Name_Id := N + $; Name_Count : constant Name_Id := N + $; - Name_CPU : constant Name_Id := N + $; -- Ada 12 + Name_CPU : constant Name_Id := N + $; -- INT Name_Default_Bit_Order : constant Name_Id := N + $; -- GNAT Name_Default_Iterator : constant Name_Id := N + $; -- GNAT Name_Definite : constant Name_Id := N + $; @@ -787,7 +792,7 @@ Name_Denorm : constant Name_Id := N + $; Name_Descriptor_Size : constant Name_Id := N + $; Name_Digits : constant Name_Id := N + $; - Name_Dispatching_Domain : constant Name_Id := N + $; -- Ada 12 + Name_Dispatching_Domain : constant Name_Id := N + $; -- INT Name_Elaborated : constant Name_Id := N + $; -- GNAT Name_Emax : constant Name_Id := N + $; -- Ada 83 Name_Enabled : constant Name_Id := N + $; -- GNAT @@ -809,7 +814,7 @@ Name_Img : constant Name_Id := N + $; -- GNAT Name_Implicit_Dereference : constant Name_Id := N + $; -- GNAT Name_Integer_Value : constant Name_Id := N + $; -- GNAT - Name_Interrupt_Priority : constant Name_Id := N + $; -- Ada 12 + Name_Interrupt_Priority : constant Name_Id := N + $; -- INT Name_Invalid_Value : constant Name_Id := N + $; -- GNAT Name_Iterator_Element : constant Name_Id := N + $; -- GNAT Name_Large : constant Name_Id := N + $; -- Ada 83 @@ -1826,6 +1831,10 @@ -- Test to see if the name N is the name of a recognized entity attribute, -- i.e. an attribute reference that returns an entity. + function Is_Internal_Attribute_Name (N : Name_Id) return Boolean; + -- Test to see if the name N is the name of an INT attribute (Name_CPU, + -- Name_Dispatching_Domain, Name_Interrupt_Priority). + function Is_Procedure_Attribute_Name (N : Name_Id) return Boolean; -- Test to see if the name N is the name of a recognized attribute that -- designates a procedure (and can therefore appear as a statement).