Commit 33985131 by Gary Dismukes Committed by Pierre-Marie de Rodat

[Ada] Fixes for various wrong and missing error messages on ACATS B85100[567]

GNAT was missing errors as well as issuing messages on legal lines in
new ACATS tests for illegal renamings of discriminant-dependent
components. Cases that are fixed include object names involving
qualified expressions, dereference cases, and generic formal access and
formal derived types. Better implements the "known to be constrained"
rules in the Ada RM.

Tested by new ACATS tests B85100[567] that are soon to be released.

2018-12-03  Gary Dismukes  <dismukes@adacore.com>

gcc/ada/

	* sem_aux.adb (Object_Type_Has_Constrained_Partial_View): Return
	True for an untagged discriminated formal derived type when
	referenced within a generic body (augments existing test for
	formal private types).
	* sem_util.adb (Is_Dependent_Component_Of_Mutable_Type): If the
	prefix of the name is a qualified expression, retrieve the
	operand of that. Add a test of whether the (possible)
	dereference prefix is a variable, and also test whether that
	prefix might just be of an access type (occurs in some implicit
	dereference cases) rather than being an explicit dereference.
	Retrieve the Original_Node of the object name's main prefix and
	handle the possibility of that being a qualified expression.
	Remove special-case code for explicit dereferences that don't
	come from source. Add test for the renaming not being within a
	generic body for proper determination of whether a formal access
	type is known to be constrained (it is within a generic spec,
	but not in the body).  Fix an existing incorrect test for
	renaming of a discriminant-dependent component of a untagged
	generic formal type being within a generic body, adding test of
	taggedness and calling In_Generic_Body (now properly checks for
	cases where the renaming is in a nongeneric body nested within a
	generic).  Return False in cases where the selector is not a
	component (or discriminant), which can occur for
	prefixed-notation calls.

From-SVN: r266759
parent cddd902d
2018-12-03 Gary Dismukes <dismukes@adacore.com>
* sem_aux.adb (Object_Type_Has_Constrained_Partial_View): Return
True for an untagged discriminated formal derived type when
referenced within a generic body (augments existing test for
formal private types).
* sem_util.adb (Is_Dependent_Component_Of_Mutable_Type): If the
prefix of the name is a qualified expression, retrieve the
operand of that. Add a test of whether the (possible)
dereference prefix is a variable, and also test whether that
prefix might just be of an access type (occurs in some implicit
dereference cases) rather than being an explicit dereference.
Retrieve the Original_Node of the object name's main prefix and
handle the possibility of that being a qualified expression.
Remove special-case code for explicit dereferences that don't
come from source. Add test for the renaming not being within a
generic body for proper determination of whether a formal access
type is known to be constrained (it is within a generic spec,
but not in the body). Fix an existing incorrect test for
renaming of a discriminant-dependent component of a untagged
generic formal type being within a generic body, adding test of
taggedness and calling In_Generic_Body (now properly checks for
cases where the renaming is in a nongeneric body nested within a
generic). Return False in cases where the selector is not a
component (or discriminant), which can occur for
prefixed-notation calls.
2018-12-03 Ed Schonberg <schonberg@adacore.com> 2018-12-03 Ed Schonberg <schonberg@adacore.com>
* sem_res.adb (Apply_Check): For array types, apply a length * sem_res.adb (Apply_Check): For array types, apply a length
......
...@@ -1472,7 +1472,8 @@ package body Sem_Aux is ...@@ -1472,7 +1472,8 @@ package body Sem_Aux is
return Has_Constrained_Partial_View (Typ) return Has_Constrained_Partial_View (Typ)
or else (In_Generic_Body (Scop) or else (In_Generic_Body (Scop)
and then Is_Generic_Type (Base_Type (Typ)) and then Is_Generic_Type (Base_Type (Typ))
and then Is_Private_Type (Base_Type (Typ)) and then (Is_Private_Type (Base_Type (Typ))
or else Is_Derived_Type (Base_Type (Typ)))
and then not Is_Tagged_Type (Typ) and then not Is_Tagged_Type (Typ)
and then not (Is_Array_Type (Typ) and then not (Is_Array_Type (Typ)
and then not Is_Constrained (Typ)) and then not Is_Constrained (Typ))
......
...@@ -14123,6 +14123,15 @@ package body Sem_Util is ...@@ -14123,6 +14123,15 @@ package body Sem_Util is
Deref := Prefix (Deref); Deref := Prefix (Deref);
end loop; end loop;
-- If the prefix is a qualified expression of a variable, then function
-- Is_Variable will return False for that because a qualified expression
-- denotes a constant view, so we need to get the name being qualified
-- so we can test below whether that's a variable (or a dereference).
if Nkind (Deref) = N_Qualified_Expression then
Deref := Expression (Deref);
end if;
-- Ada 2005: If we have a component or slice of a dereference, -- Ada 2005: If we have a component or slice of a dereference,
-- something like X.all.Y (2), and the type of X is access-to-constant, -- something like X.all.Y (2), and the type of X is access-to-constant,
-- Is_Variable will return False, because it is indeed a constant -- Is_Variable will return False, because it is indeed a constant
...@@ -14130,13 +14139,42 @@ package body Sem_Util is ...@@ -14130,13 +14139,42 @@ package body Sem_Util is
-- following condition to be True in that case. -- following condition to be True in that case.
if Is_Variable (Object) if Is_Variable (Object)
or else Is_Variable (Deref)
or else (Ada_Version >= Ada_2005 or else (Ada_Version >= Ada_2005
and then Nkind (Deref) = N_Explicit_Dereference) and then (Nkind (Deref) = N_Explicit_Dereference
or else Is_Access_Type (Etype (Deref))))
then then
if Nkind (Object) = N_Selected_Component then if Nkind (Object) = N_Selected_Component then
P := Prefix (Object);
-- If the selector is not a component, then we definitely return
-- False (it could be a function selector in a prefix form call
-- occurring in an iterator specification).
if not
Ekind_In
(Entity (Selector_Name (Object)), E_Component, E_Discriminant)
then
return False;
end if;
-- Get the original node of the prefix in case it has been
-- rewritten, which can occur, for example, in qualified
-- expression cases. Also, a discriminant check on a selected
-- component may be expanded into a dereference when removing
-- side effects, and the subtype of the original node may be
-- unconstrained.
P := Original_Node (Prefix (Object));
Prefix_Type := Etype (P); Prefix_Type := Etype (P);
-- If the prefix is a qualified expression, we want to look at
-- its operand.
if Nkind (P) = N_Qualified_Expression then
P := Expression (P);
Prefix_Type := Etype (P);
end if;
if Is_Entity_Name (P) then if Is_Entity_Name (P) then
if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then
Prefix_Type := Base_Type (Prefix_Type); Prefix_Type := Base_Type (Prefix_Type);
...@@ -14146,14 +14184,13 @@ package body Sem_Util is ...@@ -14146,14 +14184,13 @@ package body Sem_Util is
P_Aliased := True; P_Aliased := True;
end if; end if;
-- A discriminant check on a selected component may be expanded -- For explicit dereferences we get the access prefix so we can
-- into a dereference when removing side effects. Recover the -- treat this similarly to implicit dereferences and examine the
-- original node and its type, which may be unconstrained. -- kind of the access type and its designated subtype further
-- below.
elsif Nkind (P) = N_Explicit_Dereference elsif Nkind (P) = N_Explicit_Dereference then
and then not (Comes_From_Source (P)) P := Prefix (P);
then
P := Original_Node (P);
Prefix_Type := Etype (P); Prefix_Type := Etype (P);
else else
...@@ -14186,12 +14223,23 @@ package body Sem_Util is ...@@ -14186,12 +14223,23 @@ package body Sem_Util is
else pragma Assert (Ada_Version >= Ada_2005); else pragma Assert (Ada_Version >= Ada_2005);
if Is_Access_Type (Prefix_Type) then if Is_Access_Type (Prefix_Type) then
-- We need to make sure we have the base subtype, in case
-- this is actually an access subtype (whose Ekind will be
-- E_Access_Subtype).
Prefix_Type := Etype (Prefix_Type);
-- If the access type is pool-specific, and there is no -- If the access type is pool-specific, and there is no
-- constrained partial view of the designated type, then the -- constrained partial view of the designated type, then the
-- designated object is known to be constrained. -- designated object is known to be constrained. If it's a
-- formal access type and the renaming is in the generic
-- spec, we also treat it as pool-specific (known to be
-- constrained), but assume the worst if in the generic body
-- (see RM 3.3(23.3/3)).
if Ekind (Prefix_Type) = E_Access_Type if Ekind (Prefix_Type) = E_Access_Type
and then (not Is_Generic_Type (Prefix_Type)
or else not In_Generic_Body (Current_Scope))
and then not Object_Type_Has_Constrained_Partial_View and then not Object_Type_Has_Constrained_Partial_View
(Typ => Designated_Type (Prefix_Type), (Typ => Designated_Type (Prefix_Type),
Scop => Current_Scope) Scop => Current_Scope)
...@@ -14212,16 +14260,17 @@ package body Sem_Util is ...@@ -14212,16 +14260,17 @@ package body Sem_Util is
Original_Record_Component (Entity (Selector_Name (Object))); Original_Record_Component (Entity (Selector_Name (Object)));
-- As per AI-0017, the renaming is illegal in a generic body, even -- As per AI-0017, the renaming is illegal in a generic body, even
-- if the subtype is indefinite. -- if the subtype is indefinite (only applies to prefixes of an
-- untagged formal type, see RM 3.3 (23.11/3)).
-- Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable -- Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable
if not Is_Constrained (Prefix_Type) if not Is_Constrained (Prefix_Type)
and then (Is_Definite_Subtype (Prefix_Type) and then (Is_Definite_Subtype (Prefix_Type)
or else or else
(Is_Generic_Type (Prefix_Type) (not Is_Tagged_Type (Prefix_Type)
and then Ekind (Current_Scope) = E_Generic_Package and then Is_Generic_Type (Prefix_Type)
and then In_Package_Body (Current_Scope))) and then In_Generic_Body (Current_Scope)))
and then (Is_Declared_Within_Variant (Comp) and then (Is_Declared_Within_Variant (Comp)
or else Has_Discriminant_Dependent_Constraint (Comp)) or else Has_Discriminant_Dependent_Constraint (Comp))
......
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