]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Handle call to C++ constructor placed in return statement
authorJavier Miranda <miranda@adacore.com>
Sun, 4 Jan 2026 10:32:56 +0000 (10:32 +0000)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Mon, 25 May 2026 08:28:07 +0000 (10:28 +0200)
Add missing support for C++ constructor call placed in the return
statement.

gcc/ada/ChangeLog:

* sem_ch3.adb (Analyze_Object_Declaration): Report an error if the
return statement of a function with foreign convention has a call
to a C++ constructor.
* exp_ch3.adb (Expand_N_Object_Declaration): Handle initialization
expression calling a C++ constructor in an extended return statement
of a subprogram with Ada convention.

gcc/ada/exp_ch3.adb
gcc/ada/sem_ch3.adb

index 3aa86247f146c58e21e545fca2e97de1c53c36d9..b934c9061e3e4faeb42603f6e5916e949116c808 100644 (file)
@@ -8476,6 +8476,44 @@ package body Exp_Ch3 is
             --  class that has no virtual methods is an untagged limited
             --  record type.
 
+            --  a) C++ constructor call placed in a return statement. The
+            --     BIP_Object_Access param of the enclosing function has
+            --     the pointer to the object; convert it to the type of the
+            --     first formal of the called C++ constructor.
+
+            elsif Is_CPP_Constructor_Call (Expr)
+              and then Is_Return_Object (Def_Id)
+            then
+               declare
+                  Encl_Func   : constant Entity_Id :=
+                                  Return_Applies_To (Scope (Def_Id));
+                  BIP_Object  : constant Node_Id :=
+                                  Build_In_Place_Formal (Encl_Func,
+                                    BIP_Object_Access);
+                  Id_Ctor     : constant Entity_Id := Entity (Name (Expr));
+                  Id_Ref      : constant Node_Id :=
+                                  Unchecked_Convert_To (Etype (Id_Ctor),
+                                    Make_Explicit_Dereference (Loc,
+                                      New_Occurrence_Of (BIP_Object, Loc)));
+                  BIP_Obj_Ref : constant Node_Id :=
+                                  Make_Explicit_Dereference (Loc,
+                                    New_Occurrence_Of (BIP_Object, Loc));
+
+               begin
+                  Insert_List_Before_And_Analyze (N,
+                    Build_Initialization_Call (N, Id_Ref, Typ,
+                      Constructor_Ref => Expr));
+
+                  --  Generate:
+                  --    obj : T := renames BIP_Object_Access.all;
+
+                  Analyze (BIP_Obj_Ref);
+                  Rewrite_Object_Declaration_As_Renaming (N, BIP_Obj_Ref);
+                  return;
+               end;
+
+            --  b) C++ constructor call not placed in a return statement
+
             elsif Is_CPP_Constructor_Call (Expr) then
                declare
                   Id_Ref : constant Node_Id := New_Occurrence_Of (Def_Id, Loc);
index b222679f77c7e7e75719d5564ca782377f4db985..fd6d95e79b62dd88b1cee24bbdf3bf6ef003824c 100644 (file)
@@ -4865,6 +4865,19 @@ package body Sem_Ch3 is
               ("formal parameter cannot be implicitly converted to "
                & "class-wide type when Extensions_Visible is False", E);
          end if;
+
+         --  Cannot invoke a C++ constructor in the return statement of
+         --  a function with foreign convention, because the extra formal
+         --  BIP_Object_Access is not available.
+
+         if Is_CPP_Constructor_Call (E)
+           and then Is_Return_Object (Id)
+           and then Has_Foreign_Convention (Return_Applies_To (Scope (Id)))
+         then
+            Error_Msg_N
+              ("C++ constructor call in return statement of "
+               &  "function with foreign convention", E);
+         end if;
       end if;
 
       --  If the No_Streams restriction is set, check that the type of the