aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Duff <duff@adacore.com>2019-07-05 07:02:37 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-07-05 07:02:37 +0000
commitadc81ec81db382128869cd62ca4e48bd87d1d880 (patch)
tree5c8f54e936d85b4dc0ac2d46852173e695fa850b
parent7145d799a347800ea6ef5c5e3114db11469137a8 (diff)
downloadgcc-adc81ec81db382128869cd62ca4e48bd87d1d880.zip
gcc-adc81ec81db382128869cd62ca4e48bd87d1d880.tar.gz
gcc-adc81ec81db382128869cd62ca4e48bd87d1d880.tar.bz2
[Ada] Crash on exported build-in-place function
This patch fixes a bug where if a function is build-in-place, and is exported, and contains an extended_return_statement whose object is initialized with another build-in-place function call, then the compiler will crash. 2019-07-05 Bob Duff <duff@adacore.com> gcc/ada/ * exp_ch6.adb (Is_Build_In_Place_Function): Narrow the check for Has_Foreign_Convention to the imported case only. If a build-in-place function is exported, and called from Ada code, build-in-place protocols should be used. gcc/testsuite/ * gnat.dg/bip_export.adb, gnat.dg/bip_export.ads: New testcase. From-SVN: r273113
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/exp_ch6.adb16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/bip_export.adb15
-rw-r--r--gcc/testsuite/gnat.dg/bip_export.ads6
5 files changed, 39 insertions, 9 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index cac6be7..880f261 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * exp_ch6.adb (Is_Build_In_Place_Function): Narrow the check for
+ Has_Foreign_Convention to the imported case only. If a
+ build-in-place function is exported, and called from Ada code,
+ build-in-place protocols should be used.
+
2019-07-05 Ed Schonberg <schonberg@adacore.com>
* sem_util.adb (Encloing_Subprogram): If Enclosing_Dynamic_Scope
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index bd7ae2c..db9484f 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -7765,22 +7765,20 @@ package body Exp_Ch6 is
-- For now we test whether E denotes a function or access-to-function
-- type whose result subtype is inherently limited. Later this test
- -- may be revised to allow composite nonlimited types. Functions with
- -- a foreign convention or whose result type has a foreign convention
- -- never qualify.
+ -- may be revised to allow composite nonlimited types.
if Ekind_In (E, E_Function, E_Generic_Function)
or else (Ekind (E) = E_Subprogram_Type
and then Etype (E) /= Standard_Void_Type)
then
- -- Note: If the function has a foreign convention, it cannot build
- -- its result in place, so you're on your own. On the other hand,
- -- if only the return type has a foreign convention, its layout is
- -- intended to be compatible with the other language, but the build-
- -- in place machinery can ensure that the object is not copied.
+ -- If the function is imported from a foreign language, we don't do
+ -- build-in-place. Note that Import (Ada) functions can do
+ -- build-in-place. Note that it is OK for a build-in-place function
+ -- to return a type with a foreign convention; the build-in-place
+ -- machinery will ensure there is no copying.
return Is_Build_In_Place_Result_Type (Etype (E))
- and then not Has_Foreign_Convention (E)
+ and then not (Has_Foreign_Convention (E) and then Is_Imported (E))
and then not Debug_Flag_Dot_L;
else
return False;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 82b8c22..3bd1aab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/bip_export.adb, gnat.dg/bip_export.ads: New testcase.
+
2019-07-05 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/aggr25.adb, gnat.dg/aggr25.ads: New testcase.
diff --git a/gcc/testsuite/gnat.dg/bip_export.adb b/gcc/testsuite/gnat.dg/bip_export.adb
new file mode 100644
index 0000000..2935a84
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/bip_export.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+package body Bip_Export is
+ function F return T is
+ begin
+ return Result : constant T := G do
+ null;
+ end return;
+ end F;
+
+ function G return T is
+ begin
+ return (null record);
+ end G;
+end Bip_Export;
diff --git a/gcc/testsuite/gnat.dg/bip_export.ads b/gcc/testsuite/gnat.dg/bip_export.ads
new file mode 100644
index 0000000..dbbecf5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/bip_export.ads
@@ -0,0 +1,6 @@
+package Bip_Export is
+ type T is limited null record;
+ function F return T;
+ pragma Export (C, F);
+ function G return T;
+end Bip_Export;