This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Deadlock when protected procedure propagates an exception


This patch fixes a bug where a protected procedure that propagates an
exception can cause deadlock. This can happen if all of these checks are
suppressed: Access_Check, Discriminant_Check, Range_Check, Index_Check,
and Stack_Check (possibly by -gnatp), and the protected procedure calls
something that raises an exception, and that call is not an immediate
statement of the protected procedure, and is not a function used to
initialize a local variable of the protected procedure. For example, if
the call that raises an exception is inside a pragma Debug that is
inside the protected procedure, and pragma Debug is enabled by -gnata,
the deadlock can occur.

The following test must not deadlock, and should run to completion
silently.

package Debug_Prot is
   protected Prot is
      procedure P;
      entry E;
   private
      Ready_Flag : Boolean := True;
      Internal_State : Boolean := False;
   end Prot;
end Debug_Prot;

package body Debug_Prot is
   protected body Prot is
      procedure P is

         procedure transition_check is
         begin
            raise Constraint_Error;
         end transition_check;
      begin
         pragma Debug (Transition_Check);
         Internal_State := True;
      end P;

      entry E when Ready_Flag is
      begin
         null;
      end E;
   end Prot;
end Debug_Prot;

procedure Debug_Prot.Main is

   task T1;
   task T2;

   task body T1 is
   begin
      Prot.P;
   end T1;

   task body T2 is
   begin
      delay 2.0;
      Prot.E;
   end T2;

begin
   null;
end Debug_Prot.Main;

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

2017-04-28  Bob Duff  <duff@adacore.com>

	* sem_util.ads, sem_util.adb (Might_Raise): New function
	that replaces Is_Exception_Safe, but has the opposite
	sense. Is_Exception_Safe was missing various cases -- calls inside
	a pragma Debug, calls inside an 'if' or assignment statement,
	etc. Might_Raise now walks the entire subtree looking for things
	that can raise.
	* exp_ch9.adb (Is_Exception_Safe): Remove.
	(Build_Protected_Subprogram_Body): Replace call to
	Is_Exception_Safe with "not Might_Raise". Misc cleanup (use
	constants where possible).
	* exp_ch7.adb: Rename Is_Protected_Body -->
	Is_Protected_Subp_Body. A protected_body is something different
	in the grammar.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]