The compiler incorrectly allows overriding_indicators to be applied
to protected subprogram bodies (and flags a style error with -gnatyO
when they're missing), but those are disallowed by the Ada RM (see
RM-8.3.1(3-6) and AC95-00213 for confirmation of intent). This is
fixed, but the error can be changed to a warning with -gnatd.E to
ease transition for programs that were using such overriding_indicators.

The test below must report the following style warning and error
when compiled with:

$ gcc -c -gnatyO -gnatj60 prot_subp_indicator_bug.adb

prot_subp_indicator_bug.adb:17:07: (style) missing
                                   "overriding" indicator
                                   in declaration of "P"
prot_subp_indicator_bug.adb:32:07: overriding indicator not
                                   allowed for protected
                                   subprogram body

and the following warnings when compiled with:

$ gcc -c -gnatyO -gnatd.E -gnatj60 prot_subp_indicator_bug.adb

prot_subp_indicator_bug.adb:17:07: (style) missing
                                   "overriding" indicator
                                   in declaration of "P"
prot_subp_indicator_bug.adb:32:07: warning: overriding
                                   indicator not allowed
                                   for protected subprogram
                                   body

procedure Prot_Subp_Indicator_Bug is

   package Synch_Pkg is

      type Synch_Interface is synchronized interface;

      procedure P (X : out Synch_Interface) is abstract;

      procedure Q (X : in out Synch_Interface) is abstract;

   end Synch_Pkg;

   use Synch_Pkg;

   protected type Prot_Type is new Synch_Interface with

      procedure P;    -- Warning "missing overriding indicator" OK with -gnatyO

      overriding      -- OK
      procedure Q;

   end Prot_Type;

   protected body Prot_Type is

      procedure P is -- Shouldn't get warning about adding overriding indicator
      begin
         null;
      end P;

      overriding     -- Illegal (but only give a warning when using -gnatd.E)
      procedure Q is
      begin
         null;
      end Q;

   end Prot_Type;

begin
   null;
end Prot_Subp_Indicator_Bug;

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-05-21  Gary Dismukes  <dismu...@adacore.com>

        * debug.adb: Add case of illegal overriding_indicator for a
        protected subprogram body to description of -gnatd.E switch.
        * sem_ch6.adb (Verify_Overriding_Indicator): Issue error message
        for cases of giving overriding_indicators on protected subprogram
        bodies, but change this to a warning if -gnatd.E is enabled. No
        longer give a style warning about missing indicators on protected
        subprogram bodies.

Index: debug.adb
===================================================================
--- debug.adb   (revision 210697)
+++ debug.adb   (working copy)
@@ -614,6 +614,11 @@
    --
    --          Errors relating to the new rules about not defining equality
    --          too late so that composition of equality can be assured.
+   --
+   --          Errors relating to overriding indicators on protected subprogram
+   --          bodies (not an Ada 2012 incompatibility, but might cause errors
+   --          for existing programs assuming they were legal because GNAT
+   --          formerly allowed them).
 
    --  d.F  Sets GNATprove_Mode to True. This allows debugging the frontend in
    --       the special mode used by GNATprove.
Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb (revision 210697)
+++ sem_ch6.adb (working copy)
@@ -2782,6 +2782,16 @@
             elsif not Present (Overridden_Operation (Spec_Id)) then
                Error_Msg_NE
                  ("subprogram& is not overriding", Body_Spec, Spec_Id);
+
+            --  Overriding indicators aren't allowed for protected subprogram
+            --  bodies (see the Confirmation in Ada Comment AC95-00213). Change
+            --  this to a warning if -gnatd.E is enabled.
+
+            elsif Ekind (Scope (Spec_Id)) = E_Protected_Type then
+               Error_Msg_Warn := Error_To_Warning;
+               Error_Msg_N
+                 ("<overriding indicator not allowed for protected "
+                  & "subprogram body", Body_Spec);
             end if;
 
          elsif Must_Not_Override (Body_Spec) then
@@ -2797,20 +2807,37 @@
                  ("subprogram & overrides predefined operator ",
                     Body_Spec, Spec_Id);
 
-            --  If this is not a primitive operation or protected subprogram,
-            --  then the overriding indicator is altogether illegal.
+            --  Overriding indicators aren't allowed for protected subprogram
+            --  bodies (see the Confirmation in Ada Comment AC95-00213). Change
+            --  this to a warning if -gnatd.E is enabled.
 
-            elsif not Is_Primitive (Spec_Id)
-              and then Ekind (Scope (Spec_Id)) /= E_Protected_Type
-            then
+            elsif Ekind (Scope (Spec_Id)) = E_Protected_Type then
+               Error_Msg_Warn := Error_To_Warning;
+
                Error_Msg_N
+                 ("<overriding indicator not allowed " &
+                  "for protected subprogram body",
+                  Body_Spec);
+
+            --  If this is not a primitive operation, then the overriding
+            --  indicator is altogether illegal.
+
+            elsif not Is_Primitive (Spec_Id) then
+               Error_Msg_N
                  ("overriding indicator only allowed " &
                   "if subprogram is primitive",
                   Body_Spec);
             end if;
 
+         --  If checking the style rule and the operation overrides, then
+         --  issue a warning about a missing overriding_indicator. Protected
+         --  subprogram bodies are excluded from this style checking, since
+         --  they aren't primitives (even though their declarations can
+         --  override) and aren't allowed to have an overriding_indicator.
+
          elsif Style_Check
            and then Present (Overridden_Operation (Spec_Id))
+           and then Ekind (Scope (Spec_Id)) /= E_Protected_Type
          then
             pragma Assert (Unit_Declaration_Node (Body_Id) = N);
             Style.Missing_Overriding (N, Body_Id);

Reply via email to