diff mbox

[Ada] Use of convention aspect Stdcall on a record component.

Message ID 20170425103140.GA122738@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 25, 2017, 10:31 a.m. UTC
This patch fixes a spurious error on a record component whose type is an
anonymous access to subprogram, when the component carries the Windows
convention Stdcall.

The following must compile quietly:

---
package P is
     type T is record
        AF : access function (i:Integer) return integer with
           convention => stdcall;
     end record;

     --  the convention stdcall,dll,win32 are not supported,while
     --  C,CPP,FORTRAN etc. are supported.

     --  Of course,we can write as below,but one line more.

     type AF_Type is access function (i:Integer) return integer with
        convention => stdcall;

     type TOK is record
        AF : AF_Type;
     end record;
end p;

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-04-25  Ed Schonberg  <schonberg@adacore.com>

	* sem_prag.adb (Set_Convention_From_Pragma): Cleanup code for
	convention Stdcall, which has a number of exceptions. Convention
	is legal on a component declaration whose type is an anonymous
	access to subprogram.
diff mbox

Patch

Index: sem_prag.adb
===================================================================
--- sem_prag.adb	(revision 247175)
+++ sem_prag.adb	(working copy)
@@ -7401,24 +7401,32 @@ 
                     ("dispatching subprogram# cannot use Stdcall convention!",
                      Arg1);
 
-               --  Subprograms are not allowed
+               --  Several allowed cases
 
-               elsif not Is_Subprogram_Or_Generic_Subprogram (E)
+               elsif Is_Subprogram_Or_Generic_Subprogram (E)
 
                  --  A variable is OK
 
-                 and then Ekind (E) /= E_Variable
+                 or else Ekind (E) = E_Variable
 
+                 --  A component as well.  The entity does not have its
+                 --  Ekind set until the enclosing record declaration is
+                 --  fully analyzed.
+
+                 or else Nkind (Parent (E)) = N_Component_Declaration
+
                  --  An access to subprogram is also allowed
 
-                 and then not
-                   (Is_Access_Type (E)
-                     and then Ekind (Designated_Type (E)) = E_Subprogram_Type)
+                 or else (Is_Access_Type (E)
+                   and then Ekind (Designated_Type (E)) = E_Subprogram_Type)
 
                  --  Allow internal call to set convention of subprogram type
 
-                 and then not (Ekind (E) = E_Subprogram_Type)
+                 or else (Ekind (E) = E_Subprogram_Type)
                then
+                  null;
+
+               else
                   Error_Pragma_Arg
                     ("second argument of pragma% must be subprogram (type)",
                      Arg2);