if (!c_parser_next_token_is (parser, CPP_NAME))
{
invalid_category:
- c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
- "%<pointer%>");
+ c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
+ "%<pointer%> or %<all%>");
goto out_err;
}
p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
case 'a':
if (strcmp ("aggregate", p) == 0)
category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
+ else if (strcmp ("all", p) == 0)
+ category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
else
goto invalid_category;
break;
for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
+ || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
|| OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
|| (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
- == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
+ == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
+ || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
+ == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
{
enum omp_clause_defaultmap_kind cat = category;
location_t loc = OMP_CLAUSE_LOCATION (c);
- if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
+ if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
+ || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
+ && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
+ != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
p = NULL;
switch (cat)
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
p = NULL;
break;
+ case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
+ p = "all";
+ break;
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
p = "aggregate";
break;
if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
invalid_category:
- cp_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
- "%<pointer%>");
+ cp_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
+ "%<all%>");
goto out_err;
}
id = cp_lexer_peek_token (parser->lexer)->u.value;
case 'a':
if (strcmp ("aggregate", p) == 0)
category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
+ else if (strcmp ("all", p) == 0)
+ category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
else
goto invalid_category;
break;
for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
+ || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
|| OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
|| (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
- == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
+ == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
+ || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
+ == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
{
enum omp_clause_defaultmap_kind cat = category;
location_t loc = OMP_CLAUSE_LOCATION (c);
- if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
+ if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
+ || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
+ && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
+ != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
p = NULL;
switch (cat)
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
p = NULL;
break;
+ case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
+ p = "all";
+ break;
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
p = "aggregate";
break;
enum gfc_omp_defaultmap_category
{
OMP_DEFAULTMAP_CAT_UNCATEGORIZED,
+ OMP_DEFAULTMAP_CAT_ALL,
OMP_DEFAULTMAP_CAT_SCALAR,
OMP_DEFAULTMAP_CAT_AGGREGATE,
OMP_DEFAULTMAP_CAT_ALLOCATABLE,
category = OMP_DEFAULTMAP_CAT_ALLOCATABLE;
else if (gfc_match ("pointer ") == MATCH_YES)
category = OMP_DEFAULTMAP_CAT_POINTER;
+ else if (gfc_match ("all ") == MATCH_YES)
+ category = OMP_DEFAULTMAP_CAT_ALL;
else
{
- gfc_error ("Expected SCALAR, AGGREGATE, ALLOCATABLE or "
- "POINTER at %C");
+ gfc_error ("Expected SCALAR, AGGREGATE, ALLOCATABLE, "
+ "POINTER or ALL at %C");
break;
}
}
for (int i = 0; i < OMP_DEFAULTMAP_CAT_NUM; ++i)
{
if (i != category
- && category != OMP_DEFAULTMAP_CAT_UNCATEGORIZED)
+ && category != OMP_DEFAULTMAP_CAT_UNCATEGORIZED
+ && category != OMP_DEFAULTMAP_CAT_ALL
+ && i != OMP_DEFAULTMAP_CAT_UNCATEGORIZED
+ && i != OMP_DEFAULTMAP_CAT_ALL)
continue;
if (c->defaultmap[i] != OMP_DEFAULTMAP_UNSET)
{
switch (i)
{
case OMP_DEFAULTMAP_CAT_UNCATEGORIZED: break;
+ case OMP_DEFAULTMAP_CAT_ALL: pcategory = "ALL"; break;
case OMP_DEFAULTMAP_CAT_SCALAR: pcategory = "SCALAR"; break;
case OMP_DEFAULTMAP_CAT_AGGREGATE:
pcategory = "AGGREGATE";
case OMP_DEFAULTMAP_CAT_UNCATEGORIZED:
category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
break;
+ case OMP_DEFAULTMAP_CAT_ALL:
+ category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
+ break;
case OMP_DEFAULTMAP_CAT_SCALAR:
category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
break;
switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
{
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
+ case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
gdmkmin = GDMK_SCALAR;
gdmkmax = GDMK_POINTER;
break;
--- /dev/null
+/* { dg-additional-options "-fdump-tree-original -fdump-tree-gimple" } */
+
+void f()
+{
+ struct s {
+ int i;
+ };
+ int scalar1 = 5;
+ int array1[5] = {1,2,3,4,5};
+ int *ptr1 = &scalar1;
+ struct s mystruct1 = {.i = 5};
+
+ /* firstprivate + unspecified modifer. */
+ #pragma omp target defaultmap(firstprivate)
+ {
+ scalar1 = 1;
+ array1[0] = 2;
+ if (ptr1 == 0L)
+ mystruct1.i = 3;
+ }
+
+ /* equivalent: firstprivate + ALL modifer. */
+ #pragma omp target defaultmap(firstprivate : all)
+ {
+ scalar1 = 1;
+ array1[0] = 2;
+ if (ptr1 == 0L)
+ mystruct1.i = 3;
+ }
+
+ /* tofrom + ALL modifer. */
+ #pragma omp target defaultmap(tofrom : all)
+ {
+ scalar1 = 1;
+ array1[0] = 2;
+ if (ptr1 == 0L)
+ mystruct1.i = 3;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(firstprivate\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(firstprivate:all\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(tofrom:all\\)" 1 "original" } } */
+
+/* { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(firstprivate\\) firstprivate\\(mystruct1\\) firstprivate\\(ptr1\\) firstprivate\\(array1\\) firstprivate\\(scalar1\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(firstprivate:all\\) firstprivate\\(mystruct1\\) firstprivate\\(ptr1\\) firstprivate\\(array1\\) firstprivate\\(scalar1\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(tofrom:all\\) map\\(tofrom:mystruct1 \\\[len: .\\\]\\\[implicit\\\]\\) map\\(tofrom:ptr1 \\\[len: .\\\]\\\[implicit\\\]\\) map\\(tofrom:array1 \\\[len: ..\\\]\\\[implicit\\\]\\) map\\(tofrom:scalar1 \\\[len: .\\\]\\\[implicit\\\]\\)" 1 "gimple" } } */
--- /dev/null
+void f()
+{
+ struct s {
+ int i;
+ };
+ int scalar1 = 5;
+ int array1[5] = {1,2,3,4,5};
+ int *ptr1 = &scalar1;
+ struct s mystruct1 = {.i = 5};
+
+ #pragma omp target defaultmap(firstprivate ) defaultmap(firstprivate : aggregate) /* { dg-error "too many 'defaultmap' clauses with 'aggregate' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+
+ #pragma omp target defaultmap(firstprivate : all ) defaultmap(alloc : pointer) /* { dg-error "too many 'defaultmap' clauses with 'pointer' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+
+
+ #pragma omp target defaultmap(firstprivate : aggregate) defaultmap(firstprivate ) /* { dg-error "too many 'defaultmap' clauses with 'aggregate' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+
+ #pragma omp target defaultmap(alloc : pointer) defaultmap(firstprivate : all ) /* { dg-error "too many 'defaultmap' clauses with 'pointer' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+
+ #pragma omp target defaultmap(firstprivate :all ) defaultmap(firstprivate : all) /* { dg-error "too many 'defaultmap' clauses with 'all' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+ #pragma omp target defaultmap(firstprivate ) defaultmap(firstprivate) /* { dg-error "too many 'defaultmap' clauses with unspecified category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+ #pragma omp target defaultmap(firstprivate ) defaultmap(firstprivate : all) /* { dg-error "too many 'defaultmap' clauses with 'all' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+ #pragma omp target defaultmap(firstprivate : all) defaultmap(firstprivate) /* { dg-error "too many 'defaultmap' clauses with 'all' category" } */
+ {
+ scalar1 = 1; array1[0] = 2; if (ptr1 == 0L) mystruct1.i = 3;
+ }
+}
!$omp target defaultmap(bar) ! { dg-error "25: Expected ALLOC, TO, FROM, TOFROM, FIRSTPRIVATE, PRESENT, NONE or DEFAULT" }
-!$omp target defaultmap ( alloc: foo) ! { dg-error "34: Expected SCALAR, AGGREGATE, ALLOCATABLE or POINTER" }
+!$omp target defaultmap ( alloc: foo) ! { dg-error "34: Expected SCALAR, AGGREGATE, ALLOCATABLE, POINTER or ALL" }
!$omp target defaultmap(alloc:scalar) defaultmap(none:Scalar) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category SCALAR" }
--- /dev/null
+subroutine f
+ implicit none
+ type t
+ integer :: i
+ end type t
+ integer, target :: scalar
+ integer, target :: array(5)
+ integer, pointer :: ptr1, ptr2(:)
+ integer, allocatable :: alloc1, alloc2(:)
+ type(t) :: agg1, agg2(2)
+
+ scalar = 1
+ array = [1,2,3,4,5]
+ ptr1 => scalar
+ ptr2 => array
+ alloc1 = 5
+ alloc2 = [1,2]
+ agg1%i = 1
+ agg2(:)%i = [1,2]
+
+ !$omp target defaultmap(firstprivate ) defaultmap(firstprivate : aggregate) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP with unspecified category" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate : all ) defaultmap(alloc : pointer) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category ALL" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate : aggregate) defaultmap(firstprivate ) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category AGGREGATE" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(alloc : pointer) defaultmap(firstprivate : all ) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category POINTER" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate :all ) defaultmap(firstprivate : all) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category ALL" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate ) defaultmap(firstprivate) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP with unspecified category" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate ) defaultmap(firstprivate : all) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP with unspecified category" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ !$omp target defaultmap(firstprivate : all) defaultmap(firstprivate) ! { dg-error "DEFAULTMAP at .1. but prior DEFAULTMAP for category ALL" }
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+end
--- /dev/null
+! { dg-additional-options "-fdump-tree-original -fdump-tree-gimple" }
+
+subroutine f
+ implicit none
+ type t
+ integer :: i
+ end type t
+ integer, target :: scalar
+ integer, target :: array(5)
+ integer, pointer :: ptr1, ptr2(:)
+ integer, allocatable :: alloc1, alloc2(:)
+ type(t) :: agg1, agg2(2)
+
+ scalar = 1
+ array = [1,2,3,4,5]
+ ptr1 => scalar
+ ptr2 => array
+ alloc1 = 5
+ alloc2 = [1,2]
+ agg1%i = 1
+ agg2(:)%i = [1,2]
+
+ ! firstprivate + unspecified modifer.
+ !$omp target defaultmap(firstprivate)
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ ! equivalent: firstprivate + ALL modifer.
+ !$omp target defaultmap(firstprivate : all)
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+
+ ! tofrom + ALL modifer.
+ !$omp target defaultmap(tofrom : all)
+ block
+ scalar = 1;
+ array(1) = 2;
+ if (associated(ptr1)) &
+ agg1%i = 3;
+ if (associated(ptr2)) &
+ agg2(1)%i = 3;
+ if (allocated(alloc1)) &
+ alloc2(1) = 0
+ end block
+end subroutine
+
+! { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(firstprivate\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(firstprivate:all\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target defaultmap\\(tofrom:all\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(firstprivate\\) firstprivate\\(scalar\\) firstprivate\\(ptr2\\) firstprivate\\(ptr1\\) firstprivate\\(array\\) firstprivate\\(alloc2\\) firstprivate\\(alloc1\\) firstprivate\\(agg2\\) firstprivate\\(agg1\\)" 1 "gimple" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(firstprivate:all\\) firstprivate\\(scalar\\) firstprivate\\(ptr2\\) firstprivate\\(ptr1\\) firstprivate\\(array\\) firstprivate\\(alloc2\\) firstprivate\\(alloc1\\) firstprivate\\(agg2\\) firstprivate\\(agg1\\)" 1 "gimple" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target.* defaultmap\\(tofrom:all\\) map\\(tofrom:scalar \\\[len: .\\\]\\\[implicit\\\]\\) map\\(tofrom:.*ptr2.data \\\[len: .*\\\]\\\[implicit\\\]\\) map\\(to:ptr2 \\\[pointer set, len: ..\\\]\\) map\\(always_pointer:.*ptr2.data \\\[pointer assign, bias: 0\\\]\\) map\\(tofrom:\\*ptr1 \\\[len: .\\\]\\\[implicit\\\]\\) map\\(alloc:ptr1 \\\[pointer assign, bias: 0\\\]\\) map\\(tofrom:array \\\[len: ..\\\]\\\[implicit\\\]\\) map\\(tofrom:.*alloc2.data \\\[len: .*\\\]\\\[implicit\\\]\\) map\\(to:alloc2 \\\[pointer set, len: ..\\\]\\) map\\(alloc:.*alloc2.data \\\[pointer assign, bias: 0\\\]\\) map\\(tofrom:\\*alloc1 \\\[len: .\\\]\\\[implicit\\\]\\) map\\(alloc:alloc1 \\\[pointer assign, bias: 0\\\]\\) map\\(tofrom:agg2 \\\[len: .\\\]\\\[implicit\\\]\\) map\\(tofrom:agg1 \\\[len: .\\\]\\\[implicit\\\]\\)" 1 "gimple" } }
enum omp_clause_defaultmap_kind {
OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED,
+ OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL,
OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR,
OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE,
OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE,
{
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
break;
+ case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
+ pp_string (pp, ":all");
+ break;
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
pp_string (pp, ":scalar");
break;
sentinel is warned for with with @code{-Wsurprising} (enabled by
@code{-Wall}). Unknown clauses are always rejected with an error.}
@item Clauses on @code{end} directive can be on directive @tab Y @tab
+@item @code{destroy} clause with destroy-var argument on @code{depobj}
+ @tab N @tab
@item Deprecation of no-argument @code{destroy} clause on @code{depobj}
@tab N @tab
@item @code{linear} clause syntax changes and @code{step} modifier @tab Y @tab
@code{omp_invalid_device} enum/PARAMETER @tab Y @tab
@item Initial value of @var{default-device-var} ICV with
@code{OMP_TARGET_OFFLOAD=mandatory} @tab Y @tab
-@item @code{all} as @emph{implicit-behavior} for @code{defaultmap} @tab N @tab
+@item @code{all} as @emph{implicit-behavior} for @code{defaultmap} @tab Y @tab
@item @emph{interop_types} in any position of the modifier list for the @code{init} clause
of the @code{interop} construct @tab N @tab
@end multitable