[Ada] Crash on misplaced First operation for GNAT iterable type

This patch improves the handling of an improper declaaration of aspect
First for a GNAT-defined iterable type,

2018-12-11  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* sem_util.adb (Get_Actual_Subtype): Function can return type
	mark.
	(Get_Cursor_Type): Improve recovery and error message on a
	misplaced First aspect for an iterable type.

gcc/testsuite/

	* gnat.dg/iter4.adb: New testcase.

From-SVN: r267013
This commit is contained in:
Ed Schonberg 2018-12-11 11:12:16 +00:00 committed by Pierre-Marie de Rodat
parent 155f4f34d1
commit 2f42b6ead4
4 changed files with 59 additions and 1 deletions

View file

@ -1,3 +1,10 @@
2018-12-11 Ed Schonberg <schonberg@adacore.com>
* sem_util.adb (Get_Actual_Subtype): Function can return type
mark.
(Get_Cursor_Type): Improve recovery and error message on a
misplaced First aspect for an iterable type.
2018-12-11 Hristian Kirtchev <kirtchev@adacore.com>
* checks.adb: Add with and use clauses for Sem_Mech.

View file

@ -9049,6 +9049,13 @@ package body Sem_Util is
else
Decl := Build_Actual_Subtype (Typ, N);
-- The call may yield a declaration, or just return the entity
if Decl = Typ then
return Typ;
end if;
Atyp := Defining_Identifier (Decl);
-- If Build_Actual_Subtype generated a new declaration then use it
@ -9162,6 +9169,9 @@ package body Sem_Util is
if First_Op = Any_Id then
Error_Msg_N ("aspect Iterable must specify First operation", Aspect);
return Any_Type;
elsif not Analyzed (First_Op) then
Analyze (First_Op);
end if;
Cursor := Any_Type;
@ -9195,7 +9205,8 @@ package body Sem_Util is
if Cursor = Any_Type then
Error_Msg_N
("No legal primitive operation First for Iterable type", Aspect);
("primitive operation for Iterable type must appear "
& "in the same list of declarations as the type", Aspect);
end if;
return Cursor;

View file

@ -1,3 +1,7 @@
2018-12-11 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/iter4.adb: New testcase.
2018-12-11 Hristian Kirtchev <kirtchev@adacore.com>
* gnat.dg/valid4.adb, gnat.dg/valid4_pkg.adb,

View file

@ -0,0 +1,36 @@
-- { dg-do compile }
procedure Iter4 is
package Root is
type Result is tagged record
B : Boolean;
end record;
type T is tagged record
I : Integer;
end record
with Iterable => (First => Pkg.First, -- { dg-error "primitive operation for Iterable type must appear in the same list of declarations as the type" }
Next => Pkg.Next,
Has_Element => Pkg.Has_Element,
Element => Pkg.Element);
package Pkg is
function First (Dummy : T) return Natural is (0);
function Next (Dummy : T; Cursor : Natural) return Natural is
(Cursor + 1);
function Has_Element (Value : T; Cursor : Natural) return Boolean is
(Cursor <= Value.I);
function Element (Dummy : T; Cursor : Natural) return Result is
((B => Cursor mod 2 = 0));
end Pkg;
end Root;
package Derived is
type T is new Root.T with record
C : Character;
end record;
end Derived;
begin
null;
end;