Hello. A minimal reproducer follows. With gcc-9.3.0 (Debian build 13), all goes well, but gcc-10.1.0 (Debian build 3) fails to link: # /usr/bin/ld: ./pkg.o: in function `pkg__instantiation': # pkg.ads:(.text+0x9): undefined reference to `pkg__Oeq' If the source is valid Ada code (I am not quite sure), then gcc-9 is right and gcc-10 introduces a regression, else both versions should report an error instead of their current behaviour. cat > gen_proc.ads <<EOF generic type Data is private; with function Eq (L, R : Data) return Boolean is "="; procedure Gen_Proc (X : Data); EOF cat > gen_proc.adb <<EOF procedure Gen_Proc (X : Data) is B : Boolean := Eq (X, X); begin null; end Gen_Proc; EOF cat > pkg.ads <<EOF with Gen_Proc; package Pkg is type Element is null record; function "=" (L,R : Element) return Boolean is abstract; procedure Instantiation is new Gen_Proc (Element); end Pkg; EOF cat > main.adb <<EOF with Pkg; procedure Main is begin null; end Main; EOF gnatmake main.adb
ARM 3.9.3(3/2): A subprogram declared by an abstract_subprogram_declaration or a formal_abstract_subprogram_declaration is an abstract subprogram. If it is a primitive subprogram of a tagged type, then the tagged type shall be abstract. so this does not explicitly forbid abstract subprograms that are primitive to an untagged type; however: 7 A call on an abstract subprogram shall be a dispatching call; nondispatching calls to an abstract subprogram are not allowed. this implicitly requires the formal type of the controlling operand to be tagged and the actual to be class-wide. Therefore I think gcc-9.3 and gcc-10.1 should both report an error; it should be illegal to declare "=" as an abstract primitive subprogram of the untagged type Element.
This is fixed in the development version of AdaControl. Patch: - package Declarations_Store is new Scope_Manager.Scoped_Store (Asis.Declaration); + package Declarations_Store is new Scope_Manager.Scoped_Store (Asis.Declaration, + Equivalent_Keys => Asis.Elements.Is_Equal); There is a hole in the language about this case. I reported to AdaCore, and here is Tucker Taft's response: After looking through the RM, it seems that the use of an abstract "=" in this context is not directly covered, but the closest thing is the rule about what happens when you wrap a type with an abstract "=" into a record or array type. The abstract "=" raises Program_Error if it is ever invoked. See RM 4.5.2 (24.1/3): 24.1/3 {AI05-0123-1} If the primitive equals operator for an untagged record type is abstract, then Program_Error is raised at the point of any (implicit) call to that abstract subprogram. 24.f/3 Reason: An explicit call to an abstract subprogram is illegal. This rule is needed in order to define the effect of an implicit call such as a call that is part of the predefined equality operation for an enclosing composite type that has a component of an untagged record type that has an abstract primitive equals operator. For tagged types, an abstract primitive equals operator is only allowed for an abstract type, and abstract types cannot be components, so this case does not occur. So my sense is that this should *not* be a compile-time error, but rather raise Program_Error if the "=" operator of the formal type is invoked. We also should write up an AI to at least clarify this particular case. We could try to make this illegal in the generic spec, but clearly we cannot make it illegal in the generic body, because of contract issues. But I think the same argument applies here, namely that there is no need to disallow this instantiation, unless "=" is actually used, which argues for raising Program_Error rather than making it illegal.
Please attach the concatenation of the source files next time.