This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Incorrect parameter mechanism due to convention C_Pass_By_Copy


This patch corrects the Ada-C parameter passing mechanism for record types. OUT
and IN OUT parameters are now unconditionally passed by reference regardless of
whether C_Pass_By_Copy is in effect. IN parameters subject to the convention
are passed by copy, otherwise they are passed by reference.

------------
-- Source --
------------

--  utils.ads

with Interfaces.C;

package Utils is
   type Record_Type is record
      A : Interfaces.C.int;
   end record;
   pragma Convention (C_Pass_By_Copy, Record_Type);

   procedure Get_Data
     (Result    : out Interfaces.C.int;
      In_Param  :     Record_Type;
      Out_Param : out Record_Type);
   pragma Export (C, Get_Data, "get_data");
   pragma Export_Valued_Procedure (Get_Data);
end Utils;

--  utils.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Utils is
   procedure Get_Data
     (Result    : out Interfaces.C.int;
      In_Param  :     Record_Type;
      Out_Param : out Record_Type)
   is
   begin
      Put_Line ("  In data:");
      Put_Line ("   record field :" & In_Param.A'Img);

      Result      := 0;
      Out_Param.A := 42;

      Put_Line ("  Returning data:");
      Put_Line ("   return code  :" & Result'Img);
      Put_Line ("   record field :" & Out_Param.A'Img);
   end Get_Data;
end Utils;

--  driver.c

#include <stdio.h>
#include <stdlib.h>

struct record_t {
        int a;
};

extern int get_data(struct record_t in_param, struct record_t *out_param);

int main()
{
        int ret;
        struct record_t in_data, out_data;

        printf("Initializing Ada Runtime\n");
        adainit();

        in_data.a = 4;

        printf("Passing data\n");
        printf(" record field : %d\n", in_data.a);

        ret = get_data(in_data,&out_data);

        printf("Returned data\n");
        printf(" return code  : %d\n", ret);
        printf(" record field : %d\n", out_data.a);
        printf("Expected value: 42\n");

        printf("Finalizing Ada Runtime\n");
        adafinal();
}

----------------------------
-- Compilation and output --
----------------------------

$ gcc -c driver.c
$ gnatmake -q -z utils -o driver -bargs -n -largs driver.o
$ ./driver
Initializing Ada Runtime
Passing data
 record field : 4
  In data:
   record field : 4
  Returning data:
   return code  : 0
   record field : 42
Returned data
 return code  : 0
 record field : 42
Expected value: 42
Finalizing Ada Runtime

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

2012-08-06  Hristian Kirtchev  <kirtchev@adacore.com>

	* sem_mech.adb (Set_Mechanisms): OUT and IN OUT parameters are
	now unconditionally passed by reference. IN parameters subject
	to convention C_Pass_By_Copy are passed by copy, otherwise they
	are passed by reference.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]