Commit 356ffab8 by Arnaud Charlet

[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
parent ec6cfc5d
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> 2015-10-26 Ed Schonberg <schonberg@adacore.com>
* sem_disp.adb (Check_Controlling_Type): Handle properly the * sem_disp.adb (Check_Controlling_Type): Handle properly the
......
...@@ -5493,9 +5493,6 @@ package body Exp_Ch4 is ...@@ -5493,9 +5493,6 @@ package body Exp_Ch4 is
Rop : constant Node_Id := Right_Opnd (N); Rop : constant Node_Id := Right_Opnd (N);
Static : constant Boolean := Is_OK_Static_Expression (N); Static : constant Boolean := Is_OK_Static_Expression (N);
Ltyp : Entity_Id;
Rtyp : Entity_Id;
procedure Substitute_Valid_Check; procedure Substitute_Valid_Check;
-- Replaces node N by Lop'Valid. This is done when we have an explicit -- 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. -- test for the left operand being in range of its subtype.
...@@ -5505,6 +5502,49 @@ package body Exp_Ch4 is ...@@ -5505,6 +5502,49 @@ package body Exp_Ch4 is
---------------------------- ----------------------------
procedure Substitute_Valid_Check 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 begin
Rewrite (N, Rewrite (N,
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
...@@ -5513,20 +5553,27 @@ package body Exp_Ch4 is ...@@ -5513,20 +5553,27 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Restyp); Analyze_And_Resolve (N, Restyp);
-- Give warning unless overflow checking is MINIMIZED or ELIMINATED, -- Emit a warning when the left-hand operand of the membership test
-- in which case, this usage makes sense, and in any case, we have -- is a source object, otherwise the use of attribute 'Valid would be
-- actually eliminated the danger of optimization above. -- 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 Error_Msg_N
("??explicit membership test may be optimized away", N); ("??explicit membership test may be optimized away", N);
Error_Msg_N -- CODEFIX Error_Msg_N -- CODEFIX
("\??use ''Valid attribute instead", N); ("\??use ''Valid attribute instead", N);
end if; end if;
return;
end Substitute_Valid_Check; end Substitute_Valid_Check;
-- Local variables
Ltyp : Entity_Id;
Rtyp : Entity_Id;
-- Start of processing for Expand_N_In -- Start of processing for Expand_N_In
begin begin
...@@ -9767,7 +9814,7 @@ package body Exp_Ch4 is ...@@ -9767,7 +9814,7 @@ package body Exp_Ch4 is
if not Is_Discrete_Type (Etype (N)) then if not Is_Discrete_Type (Etype (N)) then
null; 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 -- Normally one would think that references like this would not
-- occur, but they do in generated code, and mean that we really -- occur, but they do in generated code, and mean that we really
-- do want to assign the discriminant. -- do want to assign the discriminant.
...@@ -10212,7 +10259,7 @@ package body Exp_Ch4 is ...@@ -10212,7 +10259,7 @@ package body Exp_Ch4 is
Cons := No_List; Cons := No_List;
-- If type is unconstrained we have to add a constraint, copied -- 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 not Is_Constrained (Target_Type) then
if Has_Discriminants (Operand_Type) then if Has_Discriminants (Operand_Type) then
......
...@@ -316,12 +316,12 @@ package body Exp_Unst is ...@@ -316,12 +316,12 @@ package body Exp_Unst is
Callee : Entity_Id; Callee : Entity_Id;
procedure Check_Static_Type (T : Entity_Id; DT : in out Boolean); 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 -- Given a type T, checks if it is a static type defined as a type
-- type with no dynamic bounds in sight. If so, the only action -- with no dynamic bounds in sight. If so, the only action is to
-- is to set Is_Static_Type True for T. If T is not a static -- set Is_Static_Type True for T. If T is not a static type, then
-- type, then all types with dynamic bounds associated with -- all types with dynamic bounds associated with T are detected,
-- T are detected, and their bounds are marked as uplevel -- and their bounds are marked as uplevel referenced if not at the
-- referenced if not at the library level, and DT is set True. -- library level, and DT is set True.
procedure Note_Uplevel_Ref procedure Note_Uplevel_Ref
(E : Entity_Id; (E : Entity_Id;
...@@ -407,7 +407,7 @@ package body Exp_Unst is ...@@ -407,7 +407,7 @@ package body Exp_Unst is
end if; end if;
end; end;
-- For record type, check all components -- For record type, check all components
elsif Is_Record_Type (T) then elsif Is_Record_Type (T) then
declare declare
...@@ -420,7 +420,7 @@ package body Exp_Unst is ...@@ -420,7 +420,7 @@ package body Exp_Unst is
end loop; end loop;
end; 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 elsif Is_Array_Type (T) then
declare declare
...@@ -467,9 +467,9 @@ package body Exp_Unst is ...@@ -467,9 +467,9 @@ package body Exp_Unst is
if Caller = Callee then if Caller = Callee then
return; return;
-- Callee may be a function that returns an array, and -- Callee may be a function that returns an array, and that has
-- that has been rewritten as a procedure. If caller is -- been rewritten as a procedure. If caller is that procedure,
-- that procedure, nothing to do either. -- nothing to do either.
elsif Ekind (Callee) = E_Function elsif Ekind (Callee) = E_Function
and then Rewritten_For_C (Callee) and then Rewritten_For_C (Callee)
...@@ -1183,8 +1183,9 @@ package body Exp_Unst is ...@@ -1183,8 +1183,9 @@ package body Exp_Unst is
-- Now we can insert the AREC declarations into the body -- Now we can insert the AREC declarations into the body
-- type ARECnT is record .. end record; -- type ARECnT is record .. end record;
-- pragma Suppress_Initialization (ARECnT); -- pragma Suppress_Initialization (ARECnT);
-- Note that we need to set the Suppress_Initialization -- Note that we need to set the Suppress_Initialization
-- flag after Decl_ARECnT has been analyzed. -- flag after Decl_ARECnT has been analyzed.
...@@ -1438,8 +1439,8 @@ package body Exp_Unst is ...@@ -1438,8 +1439,8 @@ package body Exp_Unst is
-- probably happens as a result of not properly treating -- probably happens as a result of not properly treating
-- instance bodies. To be examined ??? -- instance bodies. To be examined ???
-- If this test is omitted, then the compilation of -- If this test is omitted, then the compilation of freeze.adb
-- freeze.adb and inline.adb fail in unnesting mode. -- and inline.adb fail in unnesting mode.
if No (STJR.ARECnF) then if No (STJR.ARECnF) then
goto Continue; goto Continue;
...@@ -1451,12 +1452,11 @@ package body Exp_Unst is ...@@ -1451,12 +1452,11 @@ package body Exp_Unst is
Push_Scope (STJR.Ent); Push_Scope (STJR.Ent);
-- Now we need to rewrite the reference. We have a -- Now we need to rewrite the reference. We have a reference
-- reference is from level STJR.Lev to level STJE.Lev. -- from level STJR.Lev to level STJE.Lev. The general form of
-- The general form of the rewritten reference for -- the rewritten reference for entity X is:
-- 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 = -- where a,b,c,d .. m =
-- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev -- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev
...@@ -1562,11 +1562,10 @@ package body Exp_Unst is ...@@ -1562,11 +1562,10 @@ package body Exp_Unst is
begin begin
if Present (STT.ARECnF) then if Present (STT.ARECnF) then
-- CTJ.N is a call to a subprogram which may require -- CTJ.N is a call to a subprogram which may require a pointer
-- a pointer to an activation record. The subprogram -- to an activation record. The subprogram containing the call
-- containing the call is CTJ.From and the subprogram being -- is CTJ.From and the subprogram being called is CTJ.To, so we
-- called is CTJ.To, so we have a call from level STF.Lev to -- have a call from level STF.Lev to level STT.Lev.
-- level STT.Lev.
-- There are three possibilities: -- There are three possibilities:
...@@ -1576,10 +1575,10 @@ package body Exp_Unst is ...@@ -1576,10 +1575,10 @@ package body Exp_Unst is
if STF.Lev = STT.Lev then if STF.Lev = STT.Lev then
Extra := New_Occurrence_Of (STF.ARECnF, Loc); Extra := New_Occurrence_Of (STF.ARECnF, Loc);
-- For a call that goes down a level, we pass a pointer -- For a call that goes down a level, we pass a pointer to the
-- to the activation record constructed within the caller -- activation record constructed within the caller (which may
-- (which may be the outer level subprogram, but also may -- be the outer-level subprogram, but also may be a more deeply
-- be a more deeply nested caller). -- nested caller).
elsif STT.Lev = STF.Lev + 1 then elsif STT.Lev = STF.Lev + 1 then
Extra := New_Occurrence_Of (STF.ARECnP, Loc); Extra := New_Occurrence_Of (STF.ARECnP, Loc);
...@@ -1601,9 +1600,9 @@ package body Exp_Unst is ...@@ -1601,9 +1600,9 @@ package body Exp_Unst is
pragma Assert (STT.Lev < STF.Lev); pragma Assert (STT.Lev < STF.Lev);
Extra := New_Occurrence_Of (STF.ARECnF, Loc); 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 for K in reverse STT.Lev .. STF.Lev - 1 loop
SubX := Enclosing_Subp (SubX); SubX := Enclosing_Subp (SubX);
Extra := Extra :=
Make_Selected_Component (Loc, Make_Selected_Component (Loc,
Prefix => Extra, Prefix => Extra,
...@@ -1628,8 +1627,8 @@ package body Exp_Unst is ...@@ -1628,8 +1627,8 @@ package body Exp_Unst is
Append (ExtraP, Parameter_Associations (CTJ.N)); Append (ExtraP, Parameter_Associations (CTJ.N));
-- We need to deal with the actual parameter chain as well. -- We need to deal with the actual parameter chain as well. The
-- The newly added parameter is always the last actual. -- newly added parameter is always the last actual.
Act := First_Named_Actual (CTJ.N); Act := First_Named_Actual (CTJ.N);
......
...@@ -674,7 +674,7 @@ package body Sem_Ch6 is ...@@ -674,7 +674,7 @@ package body Sem_Ch6 is
Scope_Depth (Scope (Scope_Id)) Scope_Depth (Scope (Scope_Id))
then then
Error_Msg_N Error_Msg_N
("access discriminant in return aggregate will be " ("access discriminant in return aggregate would be "
& "a dangling reference", Obj); & "a dangling reference", Obj);
end if; end if;
end if; end if;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment