https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128044
Bug ID: 128044
Summary: Fully qualified name resolved to the current package
when instantiating a generic child
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: ada
Assignee: unassigned at gcc dot gnu.org
Reporter: lionel.draghi at free dot fr
CC: dkm at gcc dot gnu.org
Target Milestone: ---
Since GNAT 16.1, a legal Ada program is rejected when instantiating, through
the parent's instance, a generic child package whose simple name is the same
as one of its ancestors. A fully qualified reference to the ancestor inside
the generic child is resolved to the current instance of the child itself,
producing a premature-use error.
Distilled from OpenToken 6.0c; the generic formal parameters are removed,
they are not needed to trigger the error:
-- opentoken.ads
package OpenToken is end OpenToken;
-- opentoken-production.ads
generic
package OpenToken.Production is
end OpenToken.Production;
-- opentoken-production-parser.ads
generic
package OpenToken.Production.Parser is
type Instance is abstract tagged null record;
procedure Parse (Parser : in out Instance) is abstract;
end OpenToken.Production.Parser;
-- opentoken-production-parser-lalr.ads
generic
package OpenToken.Production.Parser.LALR is
end OpenToken.Production.Parser.LALR;
-- opentoken-production-parser-lalr-parser.ads
generic
package OpenToken.Production.Parser.LALR.Parser is
type Instance is new OpenToken.Production.Parser.Instance
with null record;
overriding
procedure Parse (Parser : in out Instance) is null;
end OpenToken.Production.Parser.LALR.Parser;
-- main.adb
with OpenToken.Production;
with OpenToken.Production.Parser;
with OpenToken.Production.Parser.LALR;
with OpenToken.Production.Parser.LALR.Parser;
procedure Main is
package Production is new OpenToken.Production;
package Parser is new Production.Parser;
package LALRs is new Parser.LALR;
package LALR_Parser is new LALRs.Parser;
begin
null;
end Main;
Observed (GNAT 16.1.0 and 16.2.0, default switches, Linux and Windows):
main.adb:10:04: error: instantiation error at
opentoken-production-parser-lalr-parser.ads:3
main.adb:10:04: error: type "Parser.Instance" cannot be used before end of its
declaration
main.adb:10:04: error: instantiation error at
opentoken-production-parser-lalr-parser.ads:6
main.adb:10:04: error: subprogram "Parse" is not overriding
Note that the type name quoted in the message, "Parser.Instance", does not
appear in the source, which uses the fully qualified
OpenToken.Production.Parser.Instance; the message itself betrays the
misresolution.
Expected: the program is legal and compiles (accepted by GNAT 14.2.1 and
15.2.1).
Version matrix (minimal repro, gcc -c main.adb, default switches, Linux
x86_64):
- GNAT 14.2.1 (GNAT-FSF-builds via Alire): OK
- GNAT 15.2.1 (GNAT-FSF-builds via Alire): OK
- GNAT 16.1.0 (GNAT-FSF-builds via Alire): FAIL
- GNAT 16.2.0 (Debian gcc-16): FAIL
The failure is not dependent on the language mode: on 16.1, -gnat2005 and
-gnat2012 produce the identical error, so this is not a default-standard
change effect.
Observations:
1. The generic template compiles on its own
(gcc -c opentoken-production-parser-lalr-parser.ads). The error appears
only at the last instantiation, of a generic child through the parent's
instance.
2. Renaming the grandchild to OpenToken.Production.Parser.LALR.Lalr_Parser -
so it no longer shares its simple name with its grandparent
OpenToken.Production.Parser - makes everything compile, with the reference
OpenToken.Production.Parser.Instance left unchanged. This points to a
name resolution issue in the instance context, not to a legality rule.
3. Adding "package Grandparent renames OpenToken.Production.Parser;" in the
grandchild and deriving from Grandparent.Instance does not work around
it: the error becomes
type "Grandparent.Instance" cannot be used before end of its declaration.
So, in the instance context, the ancestor subtype mark
OpenToken.Production.Parser is (incorrectly) taken to denote the current
instance of the child generic, hence the premature use.
Real-world impact: OpenToken 6.0.3 (current release in the Alire index) no
longer builds on GNAT 16 for any user instantiating
OpenToken.Production.Parser.LALR.Parser (e.g. ArchiCheck). The same sources
have been built fine with earlier GNAT releases for years.
Discussed at
https://forum.ada-lang.io/t/gnat-16-1-fully-qualified-name-resolved-to-the-current-package-when-instantiating-a-generic-child-bug/4826