Reputation: 1091
I have the following code which combines two bytes into a byte array:
pragma Restrictions (No_Exception_Propagation);
with Interfaces; use Interfaces;
procedure No_Propagation is
type Byte is new Unsigned_8;
type Byte_Array is array (Natural range <>) of Byte;
function Concat (Input_1 : Byte;
Input_2 : Byte)
return Byte_Array
is
Null_Array : Byte_Array (1 .. 0);
begin
declare
Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
begin
return Output;
exception
when Constraint_Error =>
return Null_Array;
end;
end Concat;
A, B : Byte;
begin
A := 5;
B := 0;
declare
C : Byte_Array := Concat(A, B);
begin
null;
end;
end No_Propagation;
When I compile this with:
gnatmake -gnatw.e no_propagation.adb
I get the following warning:
no_propagation.adb:16:66: warning: pragma Restrictions (No_Exception_Propagation) in effect
no_propagation.adb:16:66: warning: "Constraint_Error" may result in unhandled exception
Q1. Why am I getting a warning that a "Constraint_Error" may result in an unhandled exception when I have an exception handler in the declare block within the Concat function?
Q2. How could pasting two bytes together into a Byte_Array generate a Constraint Error?
Upvotes: 2
Views: 268
Reputation: 25491
I think your code is triggering an over-enthusiastic warning from GNAT.
To answer question 1, you will see a little further down
no_propagation.adb:20:10: warning: pragma Restrictions (No_Exception_Propagation) in effect
no_propagation.adb:20:10: warning: this handler can never be entered, and has been removed
and the reason for this is that your exception handler is too late, as @BrianDrummond suggested. You write
declare
Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
begin
return Output;
exception
when Constraint_Error =>
return Null_Array;
end;
and if any exception were to occur it would have to be in the declarative region, which is not covered by that handler. You could try to write instead
declare
Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
begin
return Output;
end;
exception
when Constraint_Error =>
return Null_Array;
but you would get the same warning; this time, I think, because the exception would need to be propagated out of the scope in which it was raised. If so, this seems to be an unfortunate consequence of the rules, or possibly an implementation issue: No_Exception_Propagation
is a GNAT extension,
This restriction guarantees that exceptions are never propagated to an outer subprogram scope. The only case in which an exception may be raised is when the handler is statically in the same subprogram, so that the effect of a raise is essentially like a goto statement. Any other raise statement (implicit or explicit) will be considered unhandled. Exception handlers are allowed, but may not contain an exception occurrence identifier (exception choice). In addition, use of the package GNAT.Current_Exception is not permitted, and reraise statements (raise with no operand) are not permitted.
As for question 2, this looks like another compiler issue. Byte_Array’(Input_1 & Input_2)
causes the warning, Byte_Array'(Input_1, Input_2)
doesn’t.
In either case, you get the same warning on the call to Concat
.
The best approach is probably to suppress all of these warnings using -gnatw.X
, "turn off warnings for non-local exception" (this is supposed to be the default, but I guess the warnings get turned on with No_Exception_Propagation
).
Upvotes: 3
Reputation: 5021
A much simpler version of your program is:
------------------------------------------------------------------
-- Simpler version of no propogation --
------------------------------------------------------------------
pragma Restrictions (No_Exception_Propagation);
with Interfaces; use Interfaces;
procedure No_Propagation2 is
type Byte is new Unsigned_8;
type Byte_Array is array (Natural range <>) of Byte;
function Concat (Input_1 : Byte;
Input_2 : Byte)
return Byte_Array
is
begin
return (Input_1, Input_2);
end Concat;
A : Byte := 5;
B : Byte := 0;
C : Byte_Array := Concat(A, B);
begin
null;
end No_Propagation2;
Upvotes: 3