[multiple changes]

2015-10-26  Hristian Kirtchev  <kirtchev@adacore.com>

	* exp_ch4.adb (Is_OK_Object_Reference): New routine.
	(Substitute_Valid_Check): Perform the 'Valid subsitution but do
	not suggest the use of the attribute if the left hand operand
	does not denote an object as it leads to illegal code.

2015-10-26  Hristian Kirtchev  <kirtchev@adacore.com>

	* exp_unst.adb: Minor reformatting.

2015-10-26  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch6.adb: Improve error msg.

From-SVN: r229341
This commit is contained in:
Arnaud Charlet 2015-10-26 12:38:57 +01:00
parent ec6cfc5dc2
commit 356ffab8a2
4 changed files with 106 additions and 45 deletions

View File

@ -1,3 +1,18 @@
2015-10-26 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch4.adb (Is_OK_Object_Reference): New routine.
(Substitute_Valid_Check): Perform the 'Valid subsitution but do
not suggest the use of the attribute if the left hand operand
does not denote an object as it leads to illegal code.
2015-10-26 Hristian Kirtchev <kirtchev@adacore.com>
* exp_unst.adb: Minor reformatting.
2015-10-26 Ed Schonberg <schonberg@adacore.com>
* sem_ch6.adb: Improve error msg.
2015-10-26 Ed Schonberg <schonberg@adacore.com>
* sem_disp.adb (Check_Controlling_Type): Handle properly the

View File

@ -5493,9 +5493,6 @@ package body Exp_Ch4 is
Rop : constant Node_Id := Right_Opnd (N);
Static : constant Boolean := Is_OK_Static_Expression (N);
Ltyp : Entity_Id;
Rtyp : Entity_Id;
procedure Substitute_Valid_Check;
-- Replaces node N by Lop'Valid. This is done when we have an explicit
-- test for the left operand being in range of its subtype.
@ -5505,6 +5502,49 @@ package body Exp_Ch4 is
----------------------------
procedure Substitute_Valid_Check is
function Is_OK_Object_Reference (Nod : Node_Id) return Boolean;
-- Determine whether arbitrary node Nod denotes a source object that
-- may safely act as prefix of attribute 'Valid.
----------------------------
-- Is_OK_Object_Reference --
----------------------------
function Is_OK_Object_Reference (Nod : Node_Id) return Boolean is
Obj_Ref : Node_Id;
begin
-- Inspect the original operand
Obj_Ref := Original_Node (Nod);
-- The object reference must be a source construct, otherwise the
-- codefix suggestion may refer to nonexistent code from a user
-- perspective.
if Comes_From_Source (Obj_Ref) then
-- Recover the actual object reference. There may be more cases
-- to consider???
loop
if Nkind_In (Obj_Ref, N_Type_Conversion,
N_Unchecked_Type_Conversion)
then
Obj_Ref := Expression (Obj_Ref);
else
exit;
end if;
end loop;
return Is_Object_Reference (Obj_Ref);
end if;
return False;
end Is_OK_Object_Reference;
-- Start of processing for Substitute_Valid_Check
begin
Rewrite (N,
Make_Attribute_Reference (Loc,
@ -5513,20 +5553,27 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Restyp);
-- Give warning unless overflow checking is MINIMIZED or ELIMINATED,
-- in which case, this usage makes sense, and in any case, we have
-- actually eliminated the danger of optimization above.
-- Emit a warning when the left-hand operand of the membership test
-- is a source object, otherwise the use of attribute 'Valid would be
-- illegal. The warning is not given when overflow checking is either
-- MINIMIZED or ELIMINATED, as the danger of optimization has been
-- eliminated above.
if Overflow_Check_Mode not in Minimized_Or_Eliminated then
if Is_OK_Object_Reference (Lop)
and then Overflow_Check_Mode not in Minimized_Or_Eliminated
then
Error_Msg_N
("??explicit membership test may be optimized away", N);
Error_Msg_N -- CODEFIX
("\??use ''Valid attribute instead", N);
end if;
return;
end Substitute_Valid_Check;
-- Local variables
Ltyp : Entity_Id;
Rtyp : Entity_Id;
-- Start of processing for Expand_N_In
begin
@ -9767,7 +9814,7 @@ package body Exp_Ch4 is
if not Is_Discrete_Type (Etype (N)) then
null;
-- Don't do this on the left hand of an assignment statement.
-- Don't do this on the left-hand side of an assignment statement.
-- Normally one would think that references like this would not
-- occur, but they do in generated code, and mean that we really
-- do want to assign the discriminant.
@ -10212,7 +10259,7 @@ package body Exp_Ch4 is
Cons := No_List;
-- If type is unconstrained we have to add a constraint, copied
-- from the actual value of the left hand side.
-- from the actual value of the left-hand side.
if not Is_Constrained (Target_Type) then
if Has_Discriminants (Operand_Type) then

View File

@ -316,12 +316,12 @@ package body Exp_Unst is
Callee : Entity_Id;
procedure Check_Static_Type (T : Entity_Id; DT : in out Boolean);
-- Given a type T, checks if it is a static type defined as a
-- type with no dynamic bounds in sight. If so, the only action
-- is to set Is_Static_Type True for T. If T is not a static
-- type, then all types with dynamic bounds associated with
-- T are detected, and their bounds are marked as uplevel
-- referenced if not at the library level, and DT is set True.
-- Given a type T, checks if it is a static type defined as a type
-- with no dynamic bounds in sight. If so, the only action is to
-- set Is_Static_Type True for T. If T is not a static type, then
-- all types with dynamic bounds associated with T are detected,
-- and their bounds are marked as uplevel referenced if not at the
-- library level, and DT is set True.
procedure Note_Uplevel_Ref
(E : Entity_Id;
@ -407,7 +407,7 @@ package body Exp_Unst is
end if;
end;
-- For record type, check all components
-- For record type, check all components
elsif Is_Record_Type (T) then
declare
@ -420,7 +420,7 @@ package body Exp_Unst is
end loop;
end;
-- For array type, check index types and component type
-- For array type, check index types and component type
elsif Is_Array_Type (T) then
declare
@ -467,9 +467,9 @@ package body Exp_Unst is
if Caller = Callee then
return;
-- Callee may be a function that returns an array, and
-- that has been rewritten as a procedure. If caller is
-- that procedure, nothing to do either.
-- Callee may be a function that returns an array, and that has
-- been rewritten as a procedure. If caller is that procedure,
-- nothing to do either.
elsif Ekind (Callee) = E_Function
and then Rewritten_For_C (Callee)
@ -1183,8 +1183,9 @@ package body Exp_Unst is
-- Now we can insert the AREC declarations into the body
-- type ARECnT is record .. end record;
-- pragma Suppress_Initialization (ARECnT);
-- type ARECnT is record .. end record;
-- pragma Suppress_Initialization (ARECnT);
-- Note that we need to set the Suppress_Initialization
-- flag after Decl_ARECnT has been analyzed.
@ -1438,8 +1439,8 @@ package body Exp_Unst is
-- probably happens as a result of not properly treating
-- instance bodies. To be examined ???
-- If this test is omitted, then the compilation of
-- freeze.adb and inline.adb fail in unnesting mode.
-- If this test is omitted, then the compilation of freeze.adb
-- and inline.adb fail in unnesting mode.
if No (STJR.ARECnF) then
goto Continue;
@ -1451,12 +1452,11 @@ package body Exp_Unst is
Push_Scope (STJR.Ent);
-- Now we need to rewrite the reference. We have a
-- reference is from level STJR.Lev to level STJE.Lev.
-- The general form of the rewritten reference for
-- entity X is:
-- Now we need to rewrite the reference. We have a reference
-- from level STJR.Lev to level STJE.Lev. The general form of
-- the rewritten reference for entity X is:
-- Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECm.X)
-- Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECm.X)
-- where a,b,c,d .. m =
-- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev
@ -1562,11 +1562,10 @@ package body Exp_Unst is
begin
if Present (STT.ARECnF) then
-- CTJ.N is a call to a subprogram which may require
-- a pointer to an activation record. The subprogram
-- containing the call is CTJ.From and the subprogram being
-- called is CTJ.To, so we have a call from level STF.Lev to
-- level STT.Lev.
-- CTJ.N is a call to a subprogram which may require a pointer
-- to an activation record. The subprogram containing the call
-- is CTJ.From and the subprogram being called is CTJ.To, so we
-- have a call from level STF.Lev to level STT.Lev.
-- There are three possibilities:
@ -1576,10 +1575,10 @@ package body Exp_Unst is
if STF.Lev = STT.Lev then
Extra := New_Occurrence_Of (STF.ARECnF, Loc);
-- For a call that goes down a level, we pass a pointer
-- to the activation record constructed within the caller
-- (which may be the outer level subprogram, but also may
-- be a more deeply nested caller).
-- For a call that goes down a level, we pass a pointer to the
-- activation record constructed within the caller (which may
-- be the outer-level subprogram, but also may be a more deeply
-- nested caller).
elsif STT.Lev = STF.Lev + 1 then
Extra := New_Occurrence_Of (STF.ARECnP, Loc);
@ -1601,9 +1600,9 @@ package body Exp_Unst is
pragma Assert (STT.Lev < STF.Lev);
Extra := New_Occurrence_Of (STF.ARECnF, Loc);
SubX := Subp_Index (CTJ.Caller);
SubX := Subp_Index (CTJ.Caller);
for K in reverse STT.Lev .. STF.Lev - 1 loop
SubX := Enclosing_Subp (SubX);
SubX := Enclosing_Subp (SubX);
Extra :=
Make_Selected_Component (Loc,
Prefix => Extra,
@ -1628,8 +1627,8 @@ package body Exp_Unst is
Append (ExtraP, Parameter_Associations (CTJ.N));
-- We need to deal with the actual parameter chain as well.
-- The newly added parameter is always the last actual.
-- We need to deal with the actual parameter chain as well. The
-- newly added parameter is always the last actual.
Act := First_Named_Actual (CTJ.N);

View File

@ -674,7 +674,7 @@ package body Sem_Ch6 is
Scope_Depth (Scope (Scope_Id))
then
Error_Msg_N
("access discriminant in return aggregate will be "
("access discriminant in return aggregate would be "
& "a dangling reference", Obj);
end if;
end if;