aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog125
-rw-r--r--gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob4
-rw-r--r--gcc/testsuite/g++.dg/parse/pr120471.C42
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr120471.C21
-rw-r--r--gcc/testsuite/gcc.dg/flex-array-counted-by.c2
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-3.c127
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4.c77
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-5.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-6.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-7.c32
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by.c111
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c51
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c36
-rw-r--r--gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c40
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c2
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/coindexed_7.f9024
-rw-r--r--gcc/testsuite/gnat.dg/specs/finalizable2.ads21
29 files changed, 1051 insertions, 26 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e78e86..eaa08db 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,128 @@
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/ubsan/pointer-counted-by-bounds-2.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-3.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-4.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-5.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds.c: New test.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/pointer-counted-by-4-char.c: New test.
+ * gcc.dg/pointer-counted-by-4-float.c: New test.
+ * gcc.dg/pointer-counted-by-4-struct.c: New test.
+ * gcc.dg/pointer-counted-by-4-union.c: New test.
+ * gcc.dg/pointer-counted-by-4.c: New test.
+ * gcc.dg/pointer-counted-by-5.c: New test.
+ * gcc.dg/pointer-counted-by-6.c: New test.
+ * gcc.dg/pointer-counted-by-7.c: New test.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/flex-array-counted-by.c: Update test.
+ * gcc.dg/pointer-counted-by-1.c: New test.
+ * gcc.dg/pointer-counted-by-2.c: New test.
+ * gcc.dg/pointer-counted-by-3.c: New test.
+ * gcc.dg/pointer-counted-by.c: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR testsuite/120919
+ * gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c (main): Change
+ sc, ss, si and sll vars from scalars to arrays of 2 elements,
+ initialize and test just the first one though.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/finalizable2.ads: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/s390/vector/vec-abs-emu.c: Add -fno-stack-protector
+ to dg-options.
+ * gcc.target/s390/vector/vec-max-emu.c: Likewise.
+ * gcc.target/s390/vector/vec-min-emu.c: Likewise.
+
+2025-07-01 Robert Dubner <rdubner@symas.com>
+
+ * cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob:
+ Append INTRINSIC keyword.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120471
+ * g++.dg/ubsan/pr120471.C: New test.
+ * g++.dg/parse/pr120471.C: New test.
+
+2025-07-01 Remi Machet <rmachet@nvidia.com>
+
+ * gcc.target/aarch64/simd/shrn2subhn.c: New test.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120847
+ * gfortran.dg/coarray/coindexed_7.f90: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/119318
+ PR testsuite/120082
+ * gcc.dg/ipa/pr119318.c (main): Expect different result on big endian
+ from little endian, on unexpected endianness or int/int128 sizes don't
+ test anything. Formatting fixes.
+
+2025-07-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/preserve-none-1.c (dg-options): Add
+ -fomit-frame-pointer.
+
+2025-07-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++.target/i386/memset-pr101366-1.C (dg-options): Add
+ -fasynchronous-unwind-tables -fdwarf2-cfi-asm.
+ * g++.target/i386/memset-pr101366-2.C: Likewise.
+ * g++.target/i386/memset-pr118276-1a.C: Likewise.
+ * g++.target/i386/memset-pr118276-1b.C: Likewise.
+ * g++.target/i386/memset-pr118276-1c.C: Likewise.
+ * gcc.target/i386/memset-pr70308-1a.c: Likewise.
+ * gcc.target/i386/memset-strategy-25.c: Likewise.
+ * gcc.target/i386/memset-strategy-28.c: Likewise.
+ * gcc.target/i386/memset-strategy-29.c: Likewise.
+ * gcc.target/i386/memset-strategy-30.c: Likewise.
+ * gcc.target/i386/pr92080-17.c: Likewise.
+ * gcc.target/i386/memset-pr70308-1b.c: Likewise. Also add
+ -fomit-frame-pointer.
+ * g++.target/i386/memset-pr108585-1a.C: (dg-options): Add
+ -fasynchronous-unwind-tables -fdwarf2-cfi-asm. Also add
+ -mno-stackrealign -fomit-frame-pointer.
+ * g++.target/i386/memset-pr108585-1b.C: Likewise.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120608
+ * c-c++-common/asan/pr120608-3.c: New test.
+ * c-c++-common/asan/pr120608-4.c: New test.
+ * g++.dg/asan/pr120608-3.C: New test.
+ * g++.dg/asan/pr120608-4.C: New test.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120843
+ * gfortran.dg/coarray/coindexed_6.f90: New test.
+
+2025-07-01 Yuao Ma <c8ef@outlook.com>
+
+ * lib/target-supports.exp (foldable_pi_based_trigonometry): New
+ effective target.
+ * gcc.dg/torture/builtin-math-9.c: New test.
+
+2025-07-01 Alexandre Oliva <oliva@adacore.com>
+
+ PR middle-end/120631
+ * gcc.dg/dfp/pr120631.c: Drop overrider of dg-do default action.
+ * gcc.dg/dfp/bitint-9.c: Likewise.
+ * gcc.dg/dfp/bitint-10.c: Likewise.
+
2025-06-30 Jeff Law <jlaw@ventanamicro.com>
PR rtl-optimization/120242
diff --git a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
index b94adf5..39a0c5b 100644
--- a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
+++ b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
@@ -5,8 +5,8 @@
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
- FUNCTION PI
- FUNCTION E.
+ FUNCTION PI INTRINSIC
+ FUNCTION E INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Z PIC 99V99.
diff --git a/gcc/testsuite/g++.dg/parse/pr120471.C b/gcc/testsuite/g++.dg/parse/pr120471.C
new file mode 100644
index 0000000..ad47e38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr120471.C
@@ -0,0 +1,42 @@
+// PR c++/120471
+// { dg-do compile }
+
+extern int a1[], a2[], a3[], a4[];
+
+int corge (int);
+
+int
+foo (int p)
+{
+ return (p ? a1 : a2)[1];
+}
+
+int
+bar (int p, int q)
+{
+ return (p ? a1 : a2)[q];
+}
+
+int
+garply (int p, int q)
+{
+ return (p ? a1 : a2)[corge (q)];
+}
+
+int
+baz (int p, int q)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[1];
+}
+
+int
+qux (int p, int q, int r)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[r];
+}
+
+int
+fred (int p, int q, int r)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[corge (r)];
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr120471.C b/gcc/testsuite/g++.dg/ubsan/pr120471.C
new file mode 100644
index 0000000..31b781f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr120471.C
@@ -0,0 +1,21 @@
+// PR c++/120471
+// { dg-do run }
+// { dg-options "-fsanitize=undefined" }
+
+volatile int b[1], a[1];
+
+void
+foo (int x)
+{
+ volatile int c = 21;
+ volatile int v = (x % 2 ? b : a)[c % 3];
+ if (v != 0)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo (1);
+ foo (2);
+}
diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by.c b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
index 16eb2c6..4fa91ff 100644
--- a/gcc/testsuite/gcc.dg/flex-array-counted-by.c
+++ b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
@@ -10,7 +10,7 @@ int x __attribute ((counted_by (size))); /* { dg-error "attribute is not allowed
struct trailing {
int count;
- int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array field" } */
+ int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
};
struct trailing_1 {
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
new file mode 100644
index 0000000..395af34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
@@ -0,0 +1,34 @@
+/* More testing the correct usage of attribute counted_by for pointer field. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+typedef struct item1 Item1;
+typedef union item2 Item2;
+
+struct pointer_array {
+ int count1;
+ Item1 *array_1 __attribute__ ((counted_by (count1)));
+ Item2 *array_2 __attribute__ ((counted_by (count2)));
+ int count2;
+} *pointer_data;
+
+struct item1 {
+ int a;
+ float b[];
+};
+
+union item2 {
+ int c;
+ float d[];
+};
+
+void foo ()
+{
+ pointer_data
+ = (struct pointer_array *) __builtin_malloc (sizeof (struct pointer_array));
+ pointer_data->array_1 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+ = (Item1 *) __builtin_malloc (sizeof (Item1) + 3 * sizeof (float));
+ pointer_data->array_2 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+ = (Item2 *) __builtin_malloc (sizeof (Item2) + 3 * sizeof (float));
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
new file mode 100644
index 0000000..1f4a278
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
@@ -0,0 +1,10 @@
+/* Testing the correct usage of attribute counted_by for pointer: _BitInt */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2 -std=c23" } */
+
+struct pointer_array {
+ _BitInt(24) count;
+ int *array __attribute__ ((counted_by (count)));
+ int *array1 __attribute__ ((counted_by (count1)));
+ _BitInt(24) count1;
+};
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
new file mode 100644
index 0000000..7005609
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
@@ -0,0 +1,127 @@
+ /* Testing the correct usage of attribute counted_by for pointer in c23,
+ multiple definitions of the same tag in same or different scopes.
+ { dg-do compile }
+ { dg-options "-std=c23" }
+ */
+
+/* Allowed redefinitions of the same struct in the same scope, with the
+ same counted_by attribute. */
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); };
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); };
+struct f {
+ int b;
+ int c;
+ int *a; }; /* { dg-error "redefinition of struct or union" } */
+
+/* Error when the counted_by attribute is defined differently. */
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (c))); }; /* { dg-error "redefinition of struct or union" } */
+
+struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); } p;
+
+void test (void)
+{
+ struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); } x;
+
+ p = x;
+}
+
+void test1 (void)
+{
+ struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (c))); } y;
+
+ p = y; /* { dg-error "incompatible types when assigning to type" } */
+}
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+};
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+};
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (n)));
+}; /* { dg-error "redefinition of struct or union" } */
+
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+} nested_p;
+
+void test_2 (void)
+{
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+} nested_x;
+
+ nested_p = nested_x;
+}
+
+void test_3 (void)
+{
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (n)));
+} nested_y;
+
+ nested_p = nested_y; /* { dg-error "incompatible types when assigning to type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
new file mode 100644
index 0000000..c404e5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
@@ -0,0 +1,6 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#define PTR_TYPE char
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
new file mode 100644
index 0000000..383d8fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
@@ -0,0 +1,6 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#define PTR_TYPE float
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
new file mode 100644
index 0000000..50246d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
@@ -0,0 +1,10 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+struct A {
+ int a;
+ char *b;
+};
+#define PTR_TYPE struct A
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
new file mode 100644
index 0000000..e786d99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
@@ -0,0 +1,10 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+union A {
+ int a;
+ float b;
+};
+#define PTR_TYPE union A
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
new file mode 100644
index 0000000..c4b3631
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
@@ -0,0 +1,77 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+#ifndef PTR_TYPE
+#define PTR_TYPE int
+#endif
+struct pointer_array {
+ int b;
+ PTR_TYPE *c;
+} *p_array;
+
+struct annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ int b;
+} *p_array_annotated;
+
+struct nested_annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *p_array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int normal_count, int attr_count)
+{
+ p_array
+ = (struct pointer_array *) malloc (sizeof (struct pointer_array));
+ p_array->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * normal_count);
+ p_array->b = normal_count;
+
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
+ p_array_annotated->b = attr_count;
+
+ p_array_nested_annotated
+ = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
+ p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
+ p_array_nested_annotated->b = attr_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test ()
+{
+ EXPECT(__builtin_dynamic_object_size(p_array->c, 1), -1);
+ EXPECT(__builtin_dynamic_object_size(p_array_annotated->c, 1),
+ p_array_annotated->b * sizeof (PTR_TYPE));
+ EXPECT(__builtin_dynamic_object_size(p_array_nested_annotated->c, 1),
+ p_array_nested_annotated->b * sizeof (PTR_TYPE));
+}
+
+void cleanup ()
+{
+ free (p_array->c);
+ free (p_array);
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+ free (p_array_nested_annotated->c);
+ free (p_array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10,10);
+ test ();
+ DONE ();
+ cleanup ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-5.c b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
new file mode 100644
index 0000000..b43ffdf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
@@ -0,0 +1,56 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ * __builtin_dynamic_object_size: when the counted_by field is negative. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+struct nested_annotated {
+ int *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int attr_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->b = attr_count;
+
+ array_nested_annotated
+ = (struct nested_annotated *)malloc (sizeof (struct nested_annotated));
+ array_nested_annotated->b = attr_count - 1;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test ()
+{
+ EXPECT(__builtin_dynamic_object_size(array_annotated->c, 1), 0);
+ EXPECT(__builtin_dynamic_object_size(array_nested_annotated->c, 1), 0);
+}
+
+void cleanup ()
+{
+ free (array_annotated);
+ free (array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (-10);
+ test ();
+ DONE ();
+ cleanup ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-6.c b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
new file mode 100644
index 0000000..355558c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
@@ -0,0 +1,56 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ * __builtin_dynamic_object_size: when the type of the pointer
+ * is casting to another type. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+typedef unsigned short u16;
+
+struct info {
+ u16 data_len;
+ char *data __attribute__((counted_by(data_len)));
+};
+
+struct foo {
+ int a;
+ int b;
+};
+
+static __attribute__((__noinline__))
+struct info *setup ()
+{
+ struct info *p;
+ size_t bytes = 3 * sizeof(struct foo);
+
+ p = (struct info *) malloc (sizeof (struct info));
+ p->data = (char *) malloc (bytes);
+ p->data_len = bytes;
+
+ return p;
+}
+
+static void
+__attribute__((__noinline__)) report (struct info *p)
+{
+ struct foo *bar = (struct foo *)p->data;
+ EXPECT(__builtin_dynamic_object_size((char *)(bar + 1), 1),
+ sizeof (struct foo) * 2);
+ EXPECT(__builtin_dynamic_object_size((char *)(bar + 2), 1),
+ sizeof (struct foo));
+}
+
+void cleanup (struct info *p)
+{
+ free (p->data);
+ free (p);
+}
+
+int main(int argc, char *argv[])
+{
+ struct info *p = setup();
+ report(p);
+ cleanup (p);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-7.c b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
new file mode 100644
index 0000000..af1ab27
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
@@ -0,0 +1,32 @@
+/* Additional test of the attribute counted_by for pointer field and its usage
+ in __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+};
+
+struct annotated __attribute__((__noinline__)) setup (int attr_count)
+{
+ struct annotated p_array_annotated;
+ p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);
+ p_array_annotated.b = attr_count;
+
+ return p_array_annotated;
+}
+
+int main(int argc, char *argv[])
+{
+ struct annotated x = setup (10);
+ int *p = x.c;
+ x = setup (20);
+ EXPECT(__builtin_dynamic_object_size (p, 1), 10 * sizeof (int));
+ EXPECT(__builtin_dynamic_object_size (x.c, 1), 20 * sizeof (int));
+ free (p);
+ free (x.c);
+ DONE ();
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c
new file mode 100644
index 0000000..0f18828
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by.c
@@ -0,0 +1,111 @@
+/* Testing the correct usage of attribute counted_by for pointer field.
+ and also mixed pointer field and FMA field in the same structure. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int size;
+int *x __attribute__ ((counted_by (size))); /* { dg-error "attribute is not allowed for a non-field declaration" } */
+
+struct pointer_array_0 {
+ int count;
+ int array __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
+ int other;
+};
+
+int count;
+struct pointer_array_1 {
+ int other;
+ int *array_1 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
+ int array_fam[] __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
+};
+
+struct pointer_array_2 {
+ float count1;
+ float count2;
+ int *array_2 __attribute__ ((counted_by (count1))); /* { dg-error "attribute is not a field declaration with an integer type" } */
+ int array_fam[] __attribute__ ((counted_by (count2))); /* { dg-error "attribute is not a field declaration with an integer type" } */
+};
+
+struct pointer_array_3 {
+ int count;
+ int *array_3 __attribute__ ((counted_by (count))) __attribute__ ((counted_by (count)));
+};
+
+struct pointer_array_4 {
+ int count1;
+ int count2;
+ int *array_4 __attribute__ ((counted_by (count1))) __attribute__ ((counted_by (count2))); /* { dg-error "conflicts with previous declaration" } */
+ float array_fam[] __attribute__ ((counted_by (count2))) __attribute__ ((counted_by (count1))); /* { dg-error "conflicts with previous declaration" } */
+};
+
+struct pointer_array_5 {
+ _Bool count;
+ int *array_5 __attribute__ ((counted_by (count)));
+};
+
+enum week {Mon, Tue, Wed};
+struct pointer_array_6 {
+ enum week days;
+ int *array_6 __attribute__ ((counted_by (days)));
+};
+
+struct pointer_array_7 {
+ int count;
+ void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */
+};
+
+struct pointer_array_8 {
+ int count;
+ int (*fpr)(int,int) __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to function" } */
+};
+
+struct item1 {
+ int a;
+ float b;
+};
+
+union item2 {
+ char *a;
+ int *b;
+};
+
+typedef struct item3 Item3;
+typedef union item4 Item4;
+
+struct item5 {
+ int a;
+ float b[];
+};
+
+/* Incomplete structure and union are allowed. */
+struct pointer_array_9 {
+ int count1;
+ int count2;
+ int count3;
+ struct item1 *array_1 __attribute__ ((counted_by (count1)));
+ union item2 *array_2 __attribute__ ((counted_by (count2)));
+ Item3 *array_3 __attribute__ ((counted_by (count3)));
+ Item4 *array_4 __attribute__ ((counted_by (count4)));
+ int count4;
+ int count5;
+ /* structure with flexible array member is not allowed. */
+ struct item5 *array_5 __attribute__ ((counted_by (count5))); /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+};
+
+struct mixed_array {
+ int count1;
+ float *array_1 __attribute__ ((counted_by (count1)));
+ float *array_2 __attribute__ ((counted_by (count1)));
+ int count2;
+ long *array_3 __attribute__ ((counted_by (count2)));
+ long array_4[] __attribute__ ((counted_by (count2)));
+};
+
+struct mixed_array_2 {
+ float *array_1 __attribute__ ((counted_by (count1)));
+ int count1;
+ float *array_2 __attribute__ ((counted_by (count1)));
+ long *array_3 __attribute__ ((counted_by (count2)));
+ int count2;
+ long array_4[] __attribute__ ((counted_by (count2)));
+};
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
new file mode 100644
index 0000000..0653ecc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
@@ -0,0 +1,51 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer combined with VLA. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 20 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+
+#include <stdlib.h>
+
+void __attribute__((__noinline__)) setup_and_test_vla (int n, int m)
+{
+ struct foo {
+ int n;
+ int (*p)[n] __attribute__((counted_by(n)));
+ } *f;
+
+ f = (struct foo *) malloc (sizeof (struct foo));
+ f->p = (int (*)[n]) malloc (m * sizeof (int[n]));
+ f->n = m;
+ f->p[m][n-1] = 1;
+ free (f->p);
+ free (f);
+ return;
+}
+
+void __attribute__((__noinline__)) setup_and_test_vla_1 (int n1, int n2, int m)
+{
+ struct foo {
+ int n;
+ int (*p)[n2][n1] __attribute__((counted_by(n)));
+ } *f;
+
+ f = (struct foo *) malloc (sizeof(struct foo));
+ f->p = (int (*)[n2][n1]) malloc (m * sizeof (int[n2][n1]));
+ f->n = m;
+ f->p[m][n2][n1] = 1;
+ free (f->p);
+ free (f);
+ return;
+}
+
+int main(int argc, char *argv[])
+{
+ setup_and_test_vla (10, 11);
+ setup_and_test_vla_1 (10, 11, 20);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
new file mode 100644
index 0000000..731422d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
@@ -0,0 +1,42 @@
+/* Test the attribute counted_by for pointer fields and its usage in bounds
+ sanitizer. when counted_by field is negative value. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->c = (int *) malloc (sizeof (int) * 10);
+ array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int annotated_index)
+{
+ array_annotated->c[annotated_index] = 2;
+}
+
+void cleanup ()
+{
+ free (array_annotated->c);
+ free (array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (-3);
+ test (2);
+ cleanup ();
+ return 0;
+}
+
+/* { dg-output "25:21: runtime error: index 2 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
new file mode 100644
index 0000000..52f202f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
@@ -0,0 +1,42 @@
+/* Test the attribute counted_by for pointer fields and its usage in bounds
+ sanitizer. when counted_by field is zero value. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->c = (int *)malloc (sizeof (int) * 10);
+ array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int annotated_index)
+{
+ array_annotated->c[annotated_index] = 2;
+}
+
+void cleanup ()
+{
+ free (array_annotated->c);
+ free (array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (0);
+ test (1);
+ cleanup ();
+ return 0;
+}
+
+/* { dg-output "25:21: runtime error: index 1 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
new file mode 100644
index 0000000..8ad7572
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
@@ -0,0 +1,40 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ p_array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
+ p_array_annotated->b = annotated_count;
+
+ return;
+}
+
+void cleanup ()
+{
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ int i;
+ setup (10);
+ for (i = 0; i < 11; i++)
+ p_array_annotated->c[i] = 2; // goes boom at i == 10
+ cleanup ();
+ return 0;
+}
+
+
+/* { dg-output "34:25: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
new file mode 100644
index 0000000..c5a1ac5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
@@ -0,0 +1,46 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct pointer_array {
+ int b;
+ int *c;
+} *p_array;
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+void __attribute__((__noinline__)) setup (int normal_count, int annotated_count)
+{
+ p_array
+ = (struct pointer_array *) malloc (sizeof (struct pointer_array));
+ p_array->c = (int *) malloc (normal_count * sizeof (int));
+ p_array->b = normal_count;
+
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
+ p_array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int normal_index, int annotated_index)
+{
+ p_array->c[normal_index] = 1;
+ p_array_annotated->c[annotated_index] = 2;
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10, 10);
+ test (10, 10);
+ return 0;
+}
+
+/* { dg-output "36:23: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
new file mode 100644
index 0000000..f90ea13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
@@ -0,0 +1,36 @@
+/* This test case checks that replacing a not+shift by a sub -1 works. */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+/* { dg-final { scan-assembler-times "\\tsubhn\\t" 6 } } */
+
+#include<arm_neon.h>
+
+uint8x8_t neg_narrow_v8hi(uint16x8_t a) {
+ uint16x8_t b = vmvnq_u16(a);
+ return vshrn_n_u16(b, 8);
+}
+
+uint8x8_t neg_narrow_vsubhn_v8hi(uint16x8_t a) {
+ uint16x8_t ones = vdupq_n_u16(0xffff);
+ return vsubhn_u16(ones, a);
+}
+
+uint16x4_t neg_narrow_v4si(uint32x4_t a) {
+ uint32x4_t b = vmvnq_u32(a);
+ return vshrn_n_u32(b, 16);
+}
+
+uint16x4_t neg_narrow_vsubhn_v4si(uint32x4_t a) {
+ uint32x4_t ones = vdupq_n_u32(0xffffffff);
+ return vsubhn_u32(ones, a);
+}
+
+uint32x2_t neg_narrow_v2di(uint64x2_t a) {
+ uint64x2_t b = ~a;
+ return vshrn_n_u64(b, 32);
+}
+
+uint32x2_t neg_narrow_vsubhn_v2di(uint64x2_t a) {
+ uint64x2_t ones = vdupq_n_u64(0xffffffffffffffff);
+ return vsubhn_u64(ones, a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
index 4b90437..fab7a52 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
@@ -27,10 +27,10 @@ int
main () {
int i;
signed long sl;
- signed char sc, expected_sc;
- signed short ss, expected_ss;
- signed int si, expected_si;
- signed long long int sll, expected_sll;
+ signed char sc[2], expected_sc;
+ signed short ss[2], expected_ss;
+ signed int si[2], expected_si;
+ signed long long int sll[2], expected_sll;
signed char *psc;
signed short *pss;
signed int *psi;
@@ -41,56 +41,56 @@ main () {
printf("Data to store [%d] = 0x%llx %llx\n", i, val.ull[1], val.ull[0]);
#endif
- psc = &sc;
- pss = &ss;
- psi = &si;
- psll = &sll;
+ psc = &sc[0];
+ pss = &ss[0];
+ psi = &si[0];
+ psll = &sll[0];
sl = 1;
- sc = 0xA1;
+ sc[0] = 0xA1;
expected_sc = 0xA1;
__builtin_altivec_tr_stxvrbx (store_data, sl, psc);
- if (expected_sc != sc & 0xFF)
+ if (expected_sc != sc[0] & 0xFF)
#if DEBUG
printf(" ERROR: Signed char = 0x%x doesn't match expected value 0x%x\n",
- sc & 0xFF, expected_sc);
+ sc[0] & 0xFF, expected_sc);
#else
abort();
#endif
- ss = 0x52;
+ ss[0] = 0x52;
expected_ss = 0x1752;
__builtin_altivec_tr_stxvrhx (store_data, sl, pss);
- if (expected_ss != ss & 0xFFFF)
+ if (expected_ss != ss[0] & 0xFFFF)
#if DEBUG
printf(" ERROR: Signed short = 0x%x doesn't match expected value 0x%x\n",
- ss, expected_ss) & 0xFFFF;
+ ss[0], expected_ss) & 0xFFFF;
#else
abort();
#endif
- si = 0x21;
+ si[0] = 0x21;
expected_si = 0x54321721;
__builtin_altivec_tr_stxvrwx (store_data, sl, psi);
- if (expected_si != si)
+ if (expected_si != si[0])
#if DEBUG
printf(" ERROR: Signed int = 0x%x doesn't match expected value 0x%x\n",
- si, expected_si);
+ si[0], expected_si);
#else
abort();
#endif
- sll = 0x12FFULL;
+ sll[0] = 0x12FFULL;
expected_sll = 0xdcba9876543217FF;
__builtin_altivec_tr_stxvrdx (store_data, sl, psll);
- if (expected_sll != sll)
+ if (expected_sll != sll[0])
#if DEBUG
printf(" ERROR: Signed long long int = 0x%llx doesn't match expected value 0x%llx\n",
- sll, expected_sll);
+ sll[0], expected_sll);
#else
abort();
#endif
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
index e0dd222..2fcaa95 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvlpq\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
index 12c7e76..16afd1d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvmxq\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
index a9bcba3..0eb0916 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvmnq\t} } } */
diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
new file mode 100644
index 0000000..0663970
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
@@ -0,0 +1,24 @@
+!{ dg-do compile }
+
+! Check PR120847 is fixed.
+
+program p
+ implicit none
+
+ type T
+ integer, allocatable :: i(:, :) [:]
+ end type T
+
+ type(T) :: o
+ integer, allocatable :: c[:]
+ integer :: i
+
+ c = 7
+
+ allocate(o%i(4, 5)[*], source=6)
+
+ do i = 1, 4
+ c = o%i(mod(i, 2), mod(i, 3))[1]
+ end do
+
+end program p
diff --git a/gcc/testsuite/gnat.dg/specs/finalizable2.ads b/gcc/testsuite/gnat.dg/specs/finalizable2.ads
new file mode 100644
index 0000000..b4a6bb1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/finalizable2.ads
@@ -0,0 +1,21 @@
+-- { dg-do compile }
+-- { dg-options "-gnatX0" }
+
+package Finalizable2 is
+
+ type Root is abstract tagged limited null record
+ with Finalizable => (Initialize => Initialize);
+
+ procedure Initialize (this : in out Root) is abstract;
+
+ type Ext (L : Natural) is new Root with record
+ A : String (1 .. L);
+ end record;
+
+ overriding procedure Initialize (this : in out Ext) is null;
+
+ function Make return Ext is (L => 3, A => "asd");
+
+ Obj : Ext := Make;
+
+end Finalizable2;