cxx-ada-vector-types

C++ Ada machine vector types

Fixed-size C++ vector typedefs and signatures are emitted as invalid <vector> placeholders, with no usable Ada machine type or calling convention.

AcceptedApplies standaloneSince 1.2.0

Where it applies.

How each patchset treats this bundle on each GCC major
PatchsetGCC 13GCC 14GCC 15GCC 16
1.2.0 (latest)Patchedgcc-13-1413.2.0Patchedgcc-13-1414.2.0Patchedgcc-15-1615.3.0Patchedgcc-15-1616.2.0
1.1.0Not applicable13.2.0Not applicable14.2.0Not applicable15.3.0Not applicable16.2.0
1.0.1Not applicable13.2.0Not applicable14.2.0Not applicable15.3.0Not applicable16.1.0
1.0.0Not applicable13.2.0Not applicable14.2.0Not applicable15.3.0Not applicable16.1.0

Explanation.

GCC represents fixed-size C++ vectors as VECTOR_TYPE, but the Ada spec dumper prints the placeholder <vector>. Both typedef declarations and every function signature using them are therefore invalid Ada.

The offending C++ includes integer and floating-point vectors passed and returned by value:

typedef int Int_Vector __attribute__((vector_size(16)));
typedef double Double_Vector __attribute__((vector_size(16)));

Int_Vector vector_identity (Int_Vector value);
Double_Vector double_vector_identity (Double_Vector value);

The unpatched mapper produces placeholders rather than types:

subtype Int_Vector is <vector>;
subtype Double_Vector is <vector>;

function vector_identity (value : <vector>) return <vector>;
function double_vector_identity (value : <vector>) return <vector>;

The corrected output declares fixed arrays with the vector's exact element count and alignment, marks them as GNAT machine vectors, and reuses their names in signatures:

type Int_Vector is array (0 .. 3) of int;
for Int_Vector'Alignment use 16;
pragma Machine_Attribute (Int_Vector, "vector_type");

type Double_Vector is array (0 .. 1) of double;
for Double_Vector'Alignment use 16;
pragma Machine_Attribute (Double_Vector, "vector_type");

function vector_identity (value : Int_Vector) return Int_Vector
with Import => True,
     Convention => Ada,
     External_Name => "_Z15vector_identityDv4_i";

Free and C-wrapper vector profiles use Convention => Ada, whose native machine-vector mode matches the target C++ vector ABI without first treating the representative Ada array as a foreign aggregate.

Vector-bearing C++ methods are a separate ABI boundary. They must retain Convention => CPP so GNAT preserves C++ method and dispatch-table identity, but direct class-wide calls are not portable: GNAT releases and targets differ on whether the Ada array is classified before or after vector_type changes its machine mode. Both conventions have produced wrong values in the tested GCC 13 and 14 matrix. The portable binding is a C++ wrapper:

extern "C" Int_Vector
cpp_transform_vector (Vector_Object *object, Int_Vector value)
{
  return object->transform (value);
}
function cpp_transform_vector
  (object : access Class_Vector_Object.Vector_Object;
   value : Int_Vector) return Int_Vector
with Import => True,
     Convention => Ada,
     External_Name => "cpp_transform_vector";

The wrapper still executes the real C++ virtual call; only the unstable cross-language method-call sequence stays on the C++ side.

Scalable SVE/RVV vectors do not have a compile-time lane count and cannot be described by an Ada fixed array. The mapper checks TYPE_VECTOR_SUBPARTS before reading it and emits the explicit <scalable_vector> unsupported marker instead of asserting or silently using the minimum runtime lane count.

The executable regression round-trips signed integer and double vectors through free functions and a C wrapper around a virtual C++ call at -O0 and -O2, so it checks generated syntax, alignment, register classification, parameter passing, return values, and preserved C++ method identity. A target-specific GCC test covers the scalable-vector guard.

Run it against an unpatched or patched compiler root:

./bundles/cxx-ada-vector-types/run-test.sh \
  TOOLCHAIN_ROOT GCC_VERSION unpatched
./bundles/cxx-ada-vector-types/run-test.sh \
  TOOLCHAIN_ROOT GCC_VERSION patched

Patch.

Variant gcc-13-14

Applies to 13.2.0, 14.2.0. Source flavors: linux, darwin_arm64.

+120 −1 3 files

Download the patch

gcc/c-family/c-ada-spec.cc +58−1modified
Unified diff for gcc/c-family/c-ada-spec.cc: original line, patched line, change, source
@@ -1512 +1512 @@dump_ada_import (pretty_printer *buffer, tree t, int spc)
15121512 const bool is_stdcall
15131513 = TREE_CODE (t) == FUNCTION_DECL
15141514 && lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t)));
1515Added line. bool uses_vector_abi = false;
1516Added line. const bool is_cpp_method
1517Added line. = TREE_CODE (t) == FUNCTION_DECL
1518Added line. && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
1519Added line.
1520Added line. if (TREE_CODE (t) == FUNCTION_DECL)
1521Added line. {
1522Added line. tree function_type = TREE_TYPE (t);
1523Added line.
1524Added line. uses_vector_abi = TREE_CODE (TREE_TYPE (function_type)) == VECTOR_TYPE;
1525Added line. for (tree args = TYPE_ARG_TYPES (function_type);
1526Added line. args && !uses_vector_abi;
1527Added line. args = TREE_CHAIN (args))
1528Added line. uses_vector_abi = TREE_CODE (TREE_VALUE (args)) == VECTOR_TYPE;
1529Added line. }
15151530
15161531 pp_string (buffer, "with Import => True, ");
15171532
@@ -1519 +1534 @@dump_ada_import (pretty_printer *buffer, tree t, int spc)
15191534
15201535 if (is_stdcall)
15211536 pp_string (buffer, "Convention => Stdcall, ");
1537Added line. else if (uses_vector_abi && !is_cpp_method)
1538Added line. /* GNAT foreign conventions can pass the representative Ada array by
1539Added line. reference before vector_type changes its machine mode. Free functions
1540Added line. therefore use the Ada convention's native vector mode; C++ methods keep
1541Added line. CPP convention for their implicit object and dispatch-table slot. */
1542Added line. pp_string (buffer, "Convention => Ada, ");
15221543 else if (name[0] == '_' && name[1] == 'Z')
15231544 pp_string (buffer, "Convention => CPP, ");
15241545 else
@@ -2130 +2168 @@dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
21302168 break;
21312169
21322170 case VECTOR_TYPE:
2133Removed line. pp_string (buffer, "<vector>");
2171Added line. if (name_only && TYPE_NAME (node))
2172Added line. dump_ada_node (buffer, TYPE_NAME (node), node, spc, limited_access,
2173Added line. true);
2174Added line. else
2175Added line. {
2176Added line. unsigned HOST_WIDE_INT subparts;
2177Added line. if (!TYPE_VECTOR_SUBPARTS (node).is_constant (&subparts))
2178Added line. pp_string (buffer, "<scalable_vector>");
2179Added line. else
2180Added line. {
2181Added line. pp_string (buffer, "array (0 .. ");
2182Added line. pp_unsigned_wide_integer (buffer, subparts - 1);
2183Added line. pp_string (buffer, ") of ");
2184Added line. dump_ada_node (buffer, TREE_TYPE (node), node, spc, limited_access,
2185Added line. true);
2186Added line. }
2187Added line. }
21342188 break;
21352189
21362190 case COMPLEX_TYPE:
@@ -2983 +3034 @@dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
29833034 pp_string (buffer, "type ");
29843035 break;
29853036
3037Added line. case VECTOR_TYPE:
3038Added line. pp_string (buffer, "type ");
3039Added line. break;
3040Added line.
29863041 case FUNCTION_TYPE:
29873042 pp_string (buffer, "-- skipped function type ");
29883043 dump_ada_node (buffer, t, type, spc, false, true);
@@ -3314 +3369 @@dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
33143369 {
33153370 pp_string (buffer, "; -- ");
33163371 dump_sloc (buffer, t);
3372Added line.
3373Added line. if (TREE_CODE (t) == TYPE_DECL
3374Added line. && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
3375Added line. {
3376Added line. newline_and_indent (buffer, spc);
3377Added line. pp_string (buffer, "for ");
3378Added line. dump_ada_node (buffer, t, type, spc, false, true);
3379Added line. pp_string (buffer, "'Alignment use ");
3380Added line. pp_decimal_int (buffer,
3381Added line. TYPE_ALIGN (TREE_TYPE (t)) / BITS_PER_UNIT);
3382Added line. pp_semicolon (buffer);
3383Added line. newline_and_indent (buffer, spc);
3384Added line. pp_string (buffer, "pragma Machine_Attribute (");
3385Added line. dump_ada_node (buffer, t, type, spc, false, true);
3386Added line. pp_string (buffer, ", \"vector_type\");");
3387Added line. }
33173388 }
33183389
33193390 return 1;
gcc/testsuite/g++.dg/ada-spec/vector-types.C +49−0new file
Unified diff for gcc/testsuite/g++.dg/ada-spec/vector-types.C: original line, patched line, change, source
@@ -0 +1 @@
1Added line. /* { dg-do compile } */
2Added line. /* { dg-options "-fdump-ada-spec-slim" } */
3Added line. /* { dg-final { scan-file vector_types_c.ads "type Int_Vector is array \(0 .. 3\) of int;" } } */
4Added line. /* { dg-final { scan-file vector_types_c.ads "for Int_Vector'Alignment use 16;" } } */
5Added line. /* { dg-final { scan-file vector_types_c.ads "pragma Machine_Attribute \(Int_Vector, \"vector_type\"\);" } } */
6Added line. /* { dg-final { scan-file vector_types_c.ads "type Double_Vector is array \(0 .. 1\) of double;" } } */
7Added line. /* { dg-final { scan-file-times vector_types_c.ads "Convention => Ada" 3 } } */
8Added line. /* { dg-final { scan-file vector_types_c.ads "function cpp_transform_vector" } } */
9Added line. /* { dg-final { scan-file vector_types_c.ads "function transform" } } */
10Added line.
11Added line. typedef int Int_Vector __attribute__((vector_size(16)));
12Added line. typedef double Double_Vector __attribute__((vector_size(16)));
13Added line.
14Added line. Int_Vector
15Added line. vector_identity (Int_Vector value)
16Added line. {
17Added line. return value;
18Added line. }
19Added line.
20Added line. Double_Vector
21Added line. double_vector_identity (Double_Vector value)
22Added line. {
23Added line. return value;
24Added line. }
25Added line.
26Added line. class Vector_Object
27Added line. {
28Added line. public:
29Added line. virtual ~Vector_Object () = default;
30Added line. virtual Int_Vector transform (Int_Vector value) { return value; }
31Added line. };
32Added line.
33Added line. extern "C" Vector_Object *create_vector_object ()
34Added line. {
35Added line. return new Vector_Object;
36Added line. }
37Added line.
38Added line. extern "C" void delete_vector_object (Vector_Object *object)
39Added line. {
40Added line. delete object;
41Added line. }
42Added line.
43Added line. extern "C" Int_Vector
44Added line. cpp_transform_vector (Vector_Object *object, Int_Vector value)
45Added line. {
46Added line. return object->transform (value);
47Added line. }
48Added line.
49Added line. /* { dg-final { cleanup-ada-spec } } */
gcc/testsuite/g++.dg/ada-spec/scalable-vector.C +13−0new file
Unified diff for gcc/testsuite/g++.dg/ada-spec/scalable-vector.C: original line, patched line, change, source
@@ -0 +1 @@
1Added line. /* { dg-do compile { target aarch64*-*-linux* } } */
2Added line. /* { dg-options "-march=armv8-a+sve -fdump-ada-spec-slim" } */
3Added line. /* { dg-final { scan-file scalable_vector_c.ads "<scalable_vector>" } } */
4Added line.
5Added line. #include <arm_sve.h>
6Added line.
7Added line. svint32_t
8Added line. scalable_identity (svint32_t value)
9Added line. {
10Added line. return value;
11Added line. }
12Added line.
13Added line. /* { dg-final { cleanup-ada-spec } } */
14

Variant gcc-15-16

Applies to 15.3.0, 16.1.0, 16.2.0. Source flavors: linux, darwin_arm64.

+118 −1 3 files

Download the patch

gcc/c-family/c-ada-spec.cc +56−1modified
Unified diff for gcc/c-family/c-ada-spec.cc: original line, patched line, change, source
@@ -1566 +1566 @@dump_ada_import (pretty_printer *pp, tree t, int spc)
15661566 const bool is_stdcall
15671567 = TREE_CODE (t) == FUNCTION_DECL
15681568 && lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t)));
1569Added line. bool uses_vector_abi = false;
1570Added line. const bool is_cpp_method
1571Added line. = TREE_CODE (t) == FUNCTION_DECL
1572Added line. && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
1573Added line.
1574Added line. if (TREE_CODE (t) == FUNCTION_DECL)
1575Added line. {
1576Added line. tree function_type = TREE_TYPE (t);
1577Added line.
1578Added line. uses_vector_abi = TREE_CODE (TREE_TYPE (function_type)) == VECTOR_TYPE;
1579Added line. for (tree args = TYPE_ARG_TYPES (function_type);
1580Added line. args && !uses_vector_abi;
1581Added line. args = TREE_CHAIN (args))
1582Added line. uses_vector_abi = TREE_CODE (TREE_VALUE (args)) == VECTOR_TYPE;
1583Added line. }
15691584
15701585 pp_string (pp, "with Import => True, ");
15711586
@@ -1573 +1588 @@dump_ada_import (pretty_printer *pp, tree t, int spc)
15731588
15741589 if (is_stdcall)
15751590 pp_string (pp, "Convention => Stdcall, ");
1591Added line. else if (uses_vector_abi && !is_cpp_method)
1592Added line. /* GNAT foreign conventions can pass the representative Ada array by
1593Added line. reference before vector_type changes its machine mode. Free functions
1594Added line. therefore use the Ada convention's native vector mode; C++ methods keep
1595Added line. CPP convention for their implicit object and dispatch-table slot. */
1596Added line. pp_string (pp, "Convention => Ada, ");
15761597 else if (name[0] == '_' && name[1] == 'Z')
15771598 pp_string (pp, "Convention => CPP, ");
15781599 else
@@ -2190 +2228 @@dump_ada_node (pretty_printer *pp, tree node, tree type, int spc,
21902228 break;
21912229
21922230 case VECTOR_TYPE:
2193Removed line. pp_string (pp, "<vector>");
2231Added line. if (name_only && TYPE_NAME (node))
2232Added line. dump_ada_node (pp, TYPE_NAME (node), node, spc, limited_access, true);
2233Added line. else
2234Added line. {
2235Added line. unsigned HOST_WIDE_INT subparts;
2236Added line. if (!TYPE_VECTOR_SUBPARTS (node).is_constant (&subparts))
2237Added line. pp_string (pp, "<scalable_vector>");
2238Added line. else
2239Added line. {
2240Added line. pp_string (pp, "array (0 .. ");
2241Added line. pp_unsigned_wide_integer (pp, subparts - 1);
2242Added line. pp_string (pp, ") of ");
2243Added line. dump_ada_node (pp, TREE_TYPE (node), node, spc, limited_access,
2244Added line. true);
2245Added line. }
2246Added line. }
21942247 break;
21952248
21962249 case COMPLEX_TYPE:
@@ -3050 +3099 @@dump_ada_declaration (pretty_printer *pp, tree t, tree type, int spc)
30503099 pp_string (pp, "type ");
30513100 break;
30523101
3102Added line. case VECTOR_TYPE:
3103Added line. pp_string (pp, "type ");
3104Added line. break;
3105Added line.
30533106 case FUNCTION_TYPE:
30543107 pp_string (pp, "-- skipped function type ");
30553108 dump_ada_node (pp, t, type, spc, false, true);
@@ -3381 +3434 @@dump_ada_declaration (pretty_printer *pp, tree t, tree type, int spc)
33813434 {
33823435 pp_string (pp, "; -- ");
33833436 dump_sloc (pp, t);
3437Added line.
3438Added line. if (TREE_CODE (t) == TYPE_DECL
3439Added line. && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
3440Added line. {
3441Added line. newline_and_indent (pp, spc);
3442Added line. pp_string (pp, "for ");
3443Added line. dump_ada_node (pp, t, type, spc, false, true);
3444Added line. pp_string (pp, "'Alignment use ");
3445Added line. pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (t)) / BITS_PER_UNIT);
3446Added line. pp_semicolon (pp);
3447Added line. newline_and_indent (pp, spc);
3448Added line. pp_string (pp, "pragma Machine_Attribute (");
3449Added line. dump_ada_node (pp, t, type, spc, false, true);
3450Added line. pp_string (pp, ", \"vector_type\");");
3451Added line. }
33843452 }
33853453
33863454 return 1;
gcc/testsuite/g++.dg/ada-spec/vector-types.C +49−0new file
Unified diff for gcc/testsuite/g++.dg/ada-spec/vector-types.C: original line, patched line, change, source
@@ -0 +1 @@
1Added line. /* { dg-do compile } */
2Added line. /* { dg-options "-fdump-ada-spec-slim" } */
3Added line. /* { dg-final { scan-file vector_types_c.ads "type Int_Vector is array \(0 .. 3\) of int;" } } */
4Added line. /* { dg-final { scan-file vector_types_c.ads "for Int_Vector'Alignment use 16;" } } */
5Added line. /* { dg-final { scan-file vector_types_c.ads "pragma Machine_Attribute \(Int_Vector, \"vector_type\"\);" } } */
6Added line. /* { dg-final { scan-file vector_types_c.ads "type Double_Vector is array \(0 .. 1\) of double;" } } */
7Added line. /* { dg-final { scan-file-times vector_types_c.ads "Convention => Ada" 3 } } */
8Added line. /* { dg-final { scan-file vector_types_c.ads "function cpp_transform_vector" } } */
9Added line. /* { dg-final { scan-file vector_types_c.ads "function transform" } } */
10Added line.
11Added line. typedef int Int_Vector __attribute__((vector_size(16)));
12Added line. typedef double Double_Vector __attribute__((vector_size(16)));
13Added line.
14Added line. Int_Vector
15Added line. vector_identity (Int_Vector value)
16Added line. {
17Added line. return value;
18Added line. }
19Added line.
20Added line. Double_Vector
21Added line. double_vector_identity (Double_Vector value)
22Added line. {
23Added line. return value;
24Added line. }
25Added line.
26Added line. class Vector_Object
27Added line. {
28Added line. public:
29Added line. virtual ~Vector_Object () = default;
30Added line. virtual Int_Vector transform (Int_Vector value) { return value; }
31Added line. };
32Added line.
33Added line. extern "C" Vector_Object *create_vector_object ()
34Added line. {
35Added line. return new Vector_Object;
36Added line. }
37Added line.
38Added line. extern "C" void delete_vector_object (Vector_Object *object)
39Added line. {
40Added line. delete object;
41Added line. }
42Added line.
43Added line. extern "C" Int_Vector
44Added line. cpp_transform_vector (Vector_Object *object, Int_Vector value)
45Added line. {
46Added line. return object->transform (value);
47Added line. }
48Added line.
49Added line. /* { dg-final { cleanup-ada-spec } } */
gcc/testsuite/g++.dg/ada-spec/scalable-vector.C +13−0new file
Unified diff for gcc/testsuite/g++.dg/ada-spec/scalable-vector.C: original line, patched line, change, source
@@ -0 +1 @@
1Added line. /* { dg-do compile { target aarch64*-*-linux* } } */
2Added line. /* { dg-options "-march=armv8-a+sve -fdump-ada-spec-slim" } */
3Added line. /* { dg-final { scan-file scalable_vector_c.ads "<scalable_vector>" } } */
4Added line.
5Added line. #include <arm_sve.h>
6Added line.
7Added line. svint32_t
8Added line. scalable_identity (svint32_t value)
9Added line. {
10Added line. return value;
11Added line. }
12Added line.
13Added line. /* { dg-final { cleanup-ada-spec } } */
14

Tests.

vector-types.C C++ · 49 lines
/* { dg-do compile } */
/* { dg-options "-fdump-ada-spec-slim" } */
/* { dg-final { scan-file vector_types_c.ads "type Int_Vector is array \(0 .. 3\) of int;" } } */
/* { dg-final { scan-file vector_types_c.ads "for Int_Vector'Alignment use 16;" } } */
/* { dg-final { scan-file vector_types_c.ads "pragma Machine_Attribute \(Int_Vector, \"vector_type\"\);" } } */
/* { dg-final { scan-file vector_types_c.ads "type Double_Vector is array \(0 .. 1\) of double;" } } */
/* { dg-final { scan-file-times vector_types_c.ads "Convention => Ada" 3 } } */
/* { dg-final { scan-file vector_types_c.ads "function cpp_transform_vector" } } */
/* { dg-final { scan-file vector_types_c.ads "function transform" } } */

typedef int Int_Vector __attribute__((vector_size(16)));
typedef double Double_Vector __attribute__((vector_size(16)));

Int_Vector
vector_identity (Int_Vector value)
{
  return value;
}

Double_Vector
double_vector_identity (Double_Vector value)
{
  return value;
}

class Vector_Object
{
public:
  virtual ~Vector_Object () = default;
  virtual Int_Vector transform (Int_Vector value) { return value; }
};

extern "C" Vector_Object *create_vector_object ()
{
  return new Vector_Object;
}

extern "C" void delete_vector_object (Vector_Object *object)
{
  delete object;
}

extern "C" Int_Vector
cpp_transform_vector (Vector_Object *object, Int_Vector value)
{
  return object->transform (value);
}

/* { dg-final { cleanup-ada-spec } } */

Download · View in repository

vector_types_consumer.adb Ada · 29 lines
with Interfaces.C; use Interfaces.C;
with Vector_Types_C;

procedure Vector_Types_Consumer is
   package Bindings renames Vector_Types_C;
   use type Bindings.Int_Vector;
   use type Bindings.Double_Vector;

   Int_Input : constant Bindings.Int_Vector := (1, -2, 3, -4);
   Double_Input : constant Bindings.Double_Vector := (1.25, -2.5);
   Object : access Bindings.Class_Vector_Object.Vector_Object :=
     Bindings.create_vector_object;
   Int_Free_Result : constant Bindings.Int_Vector :=
     Bindings.vector_identity (Int_Input);
   Double_Free_Result : constant Bindings.Double_Vector :=
     Bindings.double_vector_identity (Double_Input);
   Wrapper_Result : constant Bindings.Int_Vector :=
     Bindings.cpp_transform_vector (Object, Int_Input);
begin
   if Int_Free_Result /= Int_Input then
      raise Program_Error with "free integer vector ABI mismatch";
   elsif Double_Free_Result /= Double_Input then
      raise Program_Error with "free double vector ABI mismatch";
   elsif Wrapper_Result /= Int_Input then
      raise Program_Error with "C wrapper vector ABI mismatch";
   end if;

   Bindings.delete_vector_object (Object);
end Vector_Types_Consumer;

Download · View in repository

run-test.sh shell · 81 lines
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -ne 3 ]]; then
  echo "usage: $0 TOOLCHAIN_ROOT GCC_VERSION unpatched|patched" >&2
  exit 2
fi

root=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
source "$root/scripts/regression-common.sh"
resolve_regression_toolchain "$1"
version=$2
state=$3
[[ "$state" == unpatched || "$state" == patched ]] || {
  echo "error: state must be unpatched or patched" >&2
  exit 2
}

gxx="$REGRESSION_TOOLCHAIN/bin/g++"
[[ -x "$gxx" ]] || {
  echo "error: no g++ in $REGRESSION_TOOLCHAIN" >&2
  exit 1
}

cxx_fixture="$root/bundles/cxx-ada-vector-types/tests/vector-types.C"
ada_fixture="$root/bundles/cxx-ada-vector-types/tests/vector_types_consumer.adb"
work=$(mktemp -d "${TMPDIR:-/tmp}/gnat-cxx-ada-vector-types.XXXXXX")
trap 'rm -rf "$work"' EXIT

for optimization in 0 2; do
  case_dir="$work/O$optimization"
  mkdir -p "$case_dir"
  cp "$cxx_fixture" "$ada_fixture" "$case_dir/"
  (
    cd "$case_dir"
    "${REGRESSION_ENV[@]}" "$gxx" -c "-O$optimization" \
      -fdump-ada-spec-slim vector-types.C
  )

  spec="$case_dir/vector_types_c.ads"
  [[ -f "$spec" ]] || {
    echo "error: g++ did not generate $spec" >&2
    exit 1
  }

  set +e
  (
    cd "$case_dir"
    "${REGRESSION_ENV[@]}" "$REGRESSION_GNATMAKE" -q -f \
      "-O$optimization" vector_types_consumer.adb \
      -largs vector-types.o -lstdc++
    "${REGRESSION_ENV[@]}" ./vector_types_consumer
  ) >"$case_dir/run.log" 2>&1
  run_status=$?
  set -e

  if [[ "$state" == unpatched ]]; then
    [[ $run_status -ne 0 ]] || {
      echo "error: unpatched vector regression unexpectedly passed" >&2
      exit 1
    }
    grep -Eiq 'subtype indication expected|identifier expected' \
      "$case_dir/run.log" || {
      cat "$case_dir/run.log"
      exit 1
    }
    echo "cxx-ada-vector-types -O$optimization: expected invalid Ada (GCC $version)"
    continue
  fi

  [[ $run_status -eq 0 ]] || {
    cat "$case_dir/run.log"
    exit 1
  }
  grep -Eq 'type Int_Vector is array \(0 \.\. 3\) of int;' "$spec"
  grep -Eq 'type Double_Vector is array \(0 \.\. 1\) of double;' "$spec"
  grep -Eq 'pragma Machine_Attribute \(Int_Vector, "vector_type"\);' "$spec"
  [[ $(grep -Fc 'Convention => Ada' "$spec") -eq 3 ]]
  grep -Eq 'function transform' "$spec"
  echo "cxx-ada-vector-types -O$optimization: patched (GCC $version)"
done

Download · View in repository

Commands.

Apply the patch
patch --fuzz=0 -p1 -i bundles/cxx-ada-vector-types/patches/VARIANT.patch
Build the compiler
PATH=/path/to/bootstrap/bin:$PATH ./scripts/build-gnat.sh SOURCE BUILD INSTALL
Run the regression
./scripts/run-regressions.sh INSTALL 1.2.0 GCC_MAJOR patched

Metadata.