aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-cppbuiltin.cc2
-rw-r--r--gcc/cobol/cbldiag.h4
-rw-r--r--gcc/cobol/parse.y4
-rw-r--r--gcc/cobol/scan.l2
-rw-r--r--gcc/cobol/scan_ante.h2
-rw-r--r--gcc/cobol/show_parse.h2
-rw-r--r--gcc/cobol/util.cc4
-rw-r--r--gcc/config/aarch64/aarch64.cc37
-rw-r--r--gcc/cp/call.cc22
-rw-r--r--gcc/cp/constexpr.cc8
-rw-r--r--gcc/cp/decl.cc241
-rw-r--r--gcc/cp/parser.cc81
-rw-r--r--gcc/cp/pt.cc117
-rw-r--r--gcc/simplify-rtx.cc12
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp13.C52
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp14.C474
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp15.C474
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp16.C240
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp17.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp18.C109
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp19.C46
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp20.C53
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp21.C103
-rw-r--r--gcc/testsuite/g++.dg/cpp26/feat-cxx26.C4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90579.c7
-rw-r--r--gcc/tree-ssa-sccvn.cc22
29 files changed, 2124 insertions, 94 deletions
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 4aea902..5476d10 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1090,7 +1090,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_constexpr_exceptions=202411L");
cpp_define (pfile, "__cpp_static_assert=202306L");
cpp_define (pfile, "__cpp_placeholder_variables=202306L");
- cpp_define (pfile, "__cpp_structured_bindings=202403L");
+ cpp_define (pfile, "__cpp_structured_bindings=202411L");
cpp_define (pfile, "__cpp_deleted_function=202403L");
cpp_define (pfile, "__cpp_variadic_friend=202403L");
cpp_define (pfile, "__cpp_pack_indexing=202311L");
diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h
index dd16190..2554deb 100644
--- a/gcc/cobol/cbldiag.h
+++ b/gcc/cobol/cbldiag.h
@@ -122,8 +122,8 @@ static void
location_dump( const char func[], int line, const char tag[], const LOC& loc) {
extern int yy_flex_debug; // cppcheck-suppress shadowVariable
if( yy_flex_debug ) {
- const char *detail = gcobol_getenv("update_location"); // cppcheck-suppress knownConditionTrueFalse
- if( detail ) {
+ const char *detail = gcobol_getenv("update_location");
+ if( detail ) { // cppcheck-suppress knownConditionTrueFalse
fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n",
func, line, tag,
loc.first_line, loc.first_column, loc.last_line, loc.last_column);
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index fae96ed..59cc64d 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -10336,8 +10336,8 @@ intrinsic: function_udf
if( p != NULL ) {
auto loc = symbol_field_location(field_index(p->field));
error_msg(loc, "FUNCTION %qs has "
- "inconsistent parameter type %td (%qs)",
- keyword_str($1), p - args.data(), name_of(p->field) );
+ "inconsistent parameter type %ld (%qs)",
+ keyword_str($1), (long)(p - args.data()), name_of(p->field) );
YYERROR;
}
$$ = is_numeric(args[0].field)?
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index ba4c044..5773f09 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -123,7 +123,7 @@ NUMEDCHAR [BPVZ90/,]+{COUNT}?
NUMEDCHARS {NUMEDCHAR}([.]?{NUMEDCHAR})*
NUMED ([+-]{NUMEDCHARS}+)|({NUMEDCHARS}+[+-])
CURRENCY [A-Zfhijklmoqtuwy\x80-\xFF]{-}[ABCDEGNPRSVXZ]
-NUMEDCUR (([.]?[-$0B/Z*+,P9()V+–]|{CURRENCY}+|{COUNT})+([.][$0B/Z*+P9()V+\–])*)+
+NUMEDCUR (([.]?[$0B/Z*+,P9()V+-]|{CURRENCY}+|{COUNT})+([.][$0B/Z*+P9()V+-])*)+
NUMEDITED {NUMED}|{NUMEDCUR}
EDITED {ALPHED}|{NUMED}|{NUMEDCUR}
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 31093a6..c00826d 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -149,7 +149,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) {
}
auto nx = std::count_if(input, p, fisdigit);
if( 36 < nx ) {
- error_msg(yylloc, "significand of %s has more than 36 digits (%td)", input, nx);
+ error_msg(yylloc, "significand of %s has more than 36 digits (%ld)", input, (long)nx);
return NO_CONDITION;
}
diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h
index bd0e16f..e1a8cb2 100644
--- a/gcc/cobol/show_parse.h
+++ b/gcc/cobol/show_parse.h
@@ -500,7 +500,7 @@ class ANALYZE
int level;
inline static int analyze_level=1;
public:
- ANALYZE(const char *func_) : func(func_)
+ ANALYZE(const char *func_) : func(func_) // cppcheck-suppress noExplicitConstructor
{
level = 0;
if( getenv("Analyze") )
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index aed9483..2a7bf2b 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -1049,8 +1049,8 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const {
return TOUPPER(ch) == 'E';
} );
if( !has_exponent && data.precision() < pend - p ) {
- error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%td)",
- name, data.initial, '.', pend - p);
+ error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%ld)",
+ name, data.initial, '.', (long)(pend - p));
}
}
}
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index d30c9c7..2dbaf4a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -25435,20 +25435,41 @@ aarch64_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global)
return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
}
+/* Return true if function declaration FNDECL needs to be marked as
+ having a variant PCS. */
+
+static bool
+aarch64_is_variant_pcs (tree fndecl)
+{
+ /* Check for ABIs that preserve more registers than usual. */
+ arm_pcs pcs = (arm_pcs) fndecl_abi (fndecl).id ();
+ if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE)
+ return true;
+
+ /* Check for ABIs that allow PSTATE.SM to be 1 on entry. */
+ tree fntype = TREE_TYPE (fndecl);
+ if (aarch64_fntype_pstate_sm (fntype) != AARCH64_ISA_MODE_SM_OFF)
+ return true;
+
+ /* Check for ABIs that require PSTATE.ZA to be 1 on entry, either because
+ of ZA or ZT0. */
+ if (aarch64_fntype_pstate_za (fntype) != 0)
+ return true;
+
+ return false;
+}
+
/* Output .variant_pcs for aarch64_vector_pcs function symbols. */
static void
aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name)
{
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && aarch64_is_variant_pcs (decl))
{
- arm_pcs pcs = (arm_pcs) fndecl_abi (decl).id ();
- if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE)
- {
- fprintf (stream, "\t.variant_pcs\t");
- assemble_name (stream, name);
- fprintf (stream, "\n");
- }
+ fprintf (stream, "\t.variant_pcs\t");
+ assemble_name (stream, name);
+ fprintf (stream, "\n");
}
}
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 9283d97..63cad2a 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -7904,28 +7904,6 @@ extract_call_expr (tree call)
call = TREE_OPERAND (call, 0);
if (TREE_CODE (call) == TARGET_EXPR)
call = TARGET_EXPR_INITIAL (call);
- if (cxx_dialect >= cxx20)
- switch (TREE_CODE (call))
- {
- /* C++20 rewritten comparison operators. */
- case TRUTH_NOT_EXPR:
- call = TREE_OPERAND (call, 0);
- break;
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case SPACESHIP_EXPR:
- {
- tree op0 = TREE_OPERAND (call, 0);
- if (integer_zerop (op0))
- call = TREE_OPERAND (call, 1);
- else
- call = op0;
- }
- break;
- default:;
- }
if (TREE_CODE (call) != CALL_EXPR
&& TREE_CODE (call) != AGGR_INIT_EXPR
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index b8ac454..eabf7f8 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -11615,12 +11615,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
}
return false;
}
+ tree ve = DECL_VALUE_EXPR (t);
/* Treat __PRETTY_FUNCTION__ inside a template function as
potentially-constant. */
- else if (DECL_PRETTY_FUNCTION_P (t)
- && DECL_VALUE_EXPR (t) == error_mark_node)
+ if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
return true;
- return RECUR (DECL_VALUE_EXPR (t), rval);
+ if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
+ return RECUR (TREE_VEC_ELT (ve, 0), rval);
+ return RECUR (ve, rval);
}
if (want_rval
&& (now || !var_in_maybe_constexpr_fn (t))
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 8122fca..ab5b0c9 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9748,7 +9748,7 @@ get_tuple_size (tree type)
/* Return std::tuple_element<I,TYPE>::type. */
static tree
-get_tuple_element_type (tree type, unsigned i)
+get_tuple_element_type (tree type, unsigned HOST_WIDE_INT i)
{
tree args = make_tree_vec (2);
TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
@@ -9764,7 +9764,7 @@ get_tuple_element_type (tree type, unsigned i)
/* Return e.get<i>() or get<i>(e). */
static tree
-get_tuple_decomp_init (tree decl, unsigned i)
+get_tuple_decomp_init (tree decl, unsigned HOST_WIDE_INT i)
{
tree targs = make_tree_vec (1);
TREE_VEC_ELT (targs, 0) = build_int_cst (integer_type_node, i);
@@ -9870,6 +9870,19 @@ cp_maybe_mangle_decomp (tree decl, cp_decomp *decomp)
}
}
+/* Append #i to DECL_NAME (decl). */
+
+static void
+set_sb_pack_name (tree decl, unsigned HOST_WIDE_INT i)
+{
+ tree name = DECL_NAME (decl);
+ size_t len = IDENTIFIER_LENGTH (name) + 22;
+ char *n = XALLOCAVEC (char, len);
+ snprintf (n, len, "%s#" HOST_WIDE_INT_PRINT_UNSIGNED,
+ IDENTIFIER_POINTER (name), i);
+ DECL_NAME (decl) = get_identifier (n);
+}
+
/* Finish a decomposition declaration. DECL is the underlying declaration
"e", FIRST is the head of a chain of decls for the individual identifiers
chained through DECL_CHAIN in reverse order and COUNT is the number of
@@ -9926,10 +9939,13 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
auto_vec<tree, 16> v;
v.safe_grow (count, true);
tree d = first;
+ int pack = -1;
for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
{
v[count - i - 1] = d;
fit_decomposition_lang_decl (d, decl);
+ if (DECL_PACK_P (d))
+ pack = count - i - 1;
}
tree type = TREE_TYPE (decl);
@@ -9951,6 +9967,14 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
tree eltype = NULL_TREE;
unsigned HOST_WIDE_INT eltscnt = 0;
+ /* Structured binding packs when initializer is non-dependent should
+ have their DECL_VALUE_EXPR set to a TREE_VEC. First two elements
+ of that TREE_VEC are the base and index, what is normally represented
+ as DECL_VALUE_EXPR ARRAY_REF <base, index> where index is the index
+ of the pack first element. The remaining elements of the TREE_VEC
+ are VAR_DECLs for the pack elements. */
+ tree packv = NULL_TREE;
+
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree nelts;
@@ -9969,7 +9993,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
goto error_out;
}
eltscnt = tree_to_uhwi (nelts);
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
{
cnt_mismatch:
auto_diagnostic_group d;
@@ -9990,12 +10014,37 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
eltype = TREE_TYPE (type);
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = unshare_expr (dexp);
+ a = build4 (ARRAY_REF, eltype, a, size_int (j + pack),
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
- t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
+ t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
@@ -10004,17 +10053,41 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
else if (TREE_CODE (type) == COMPLEX_TYPE)
{
eltscnt = 2;
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = build1 (pack + j ? IMAGPART_EXPR : REALPART_EXPR, eltype,
+ unshare_expr (dexp));
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
- t = build1 (i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
+ t = build1 (j ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
@@ -10026,19 +10099,47 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
error_at (loc, "cannot decompose variable length vector %qT", type);
goto error_out;
}
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = unshare_expr (dexp);
+ location_t loc = DECL_SOURCE_LOCATION (t);
+ tree s = size_int (j + pack);
+ convert_vector_to_array_for_subscript (loc, &a, s);
+ a = build4 (ARRAY_REF, eltype, a, s,
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
- &t, size_int (i));
- t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+ &t, size_int (j));
+ t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
@@ -10062,11 +10163,11 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
goto error_out;
}
eltscnt = tree_to_uhwi (tsize);
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
- if (test_p)
+ if (test_p && eltscnt)
return true;
- if (!processing_template_decl && DECL_DECOMP_BASE (decl))
+ if (!processing_template_decl && DECL_DECOMP_BASE (decl) && eltscnt)
{
/* For structured bindings used in conditions we need to evaluate
the conversion of decl (aka e in the standard) to bool or
@@ -10096,16 +10197,70 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
location_t sloc = input_location;
location_t dloc = DECL_SOURCE_LOCATION (v[i]);
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ input_location = dloc;
+ tree init = get_tuple_decomp_init (decl, j + pack);
+ tree eltype = (init == error_mark_node ? error_mark_node
+ : get_tuple_element_type (type, j + pack));
+ input_location = sloc;
+
+ if (VOID_TYPE_P (eltype))
+ {
+ error ("%<std::tuple_element<%wu, %T>::type%> is "
+ "%<void%>", j + pack, type);
+ eltype = error_mark_node;
+ }
+ if (init == error_mark_node || eltype == error_mark_node)
+ {
+ inform (dloc, "in initialization of structured binding "
+ "pack %qD", v[pack]);
+ goto error_out;
+ }
+ if (j == 0
+ && !processing_template_decl
+ && TREE_STATIC (decl))
+ {
+ sorry_at (dloc, "mangling of structured binding pack "
+ "elements not implemented yet");
+ goto error_out;
+ }
+ maybe_push_decl (t);
+ /* Save the decltype away before reference collapse. */
+ hash_map_safe_put<hm_ggc> (decomp_type_table, t, eltype);
+ eltype = cp_build_reference_type (eltype, !lvalue_p (init));
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ DECL_HAS_VALUE_EXPR_P (t) = 0;
+ if (!processing_template_decl)
+ {
+ copy_linkage (t, decl);
+ cp_finish_decl (t, init, /*constexpr*/false,
+ /*asm*/NULL_TREE, LOOKUP_NORMAL);
+ }
+ }
+ continue;
+ }
+
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
input_location = dloc;
- tree init = get_tuple_decomp_init (decl, i);
+ tree init = get_tuple_decomp_init (decl, j);
tree eltype = (init == error_mark_node ? error_mark_node
- : get_tuple_element_type (type, i));
+ : get_tuple_element_type (type, j));
input_location = sloc;
if (VOID_TYPE_P (eltype))
{
- error ("%<std::tuple_element<%u, %T>::type%> is %<void%>",
- i, type);
+ error ("%<std::tuple_element<%wu, %T>::type%> is %<void%>",
+ j, type);
eltype = error_mark_node;
}
if (init == error_mark_node || eltype == error_mark_node)
@@ -10159,6 +10314,12 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
goto error_out;
else if (btype == NULL_TREE)
{
+ if (pack == 0 && count == 1)
+ {
+ eltscnt = 0;
+ packv = make_tree_vec (2);
+ goto done;
+ }
error_at (loc, "cannot decompose class type %qT without non-static "
"data members", type);
goto error_out;
@@ -10170,7 +10331,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
continue;
else
eltscnt++;
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
tree t = dexp;
if (type != btype)
@@ -10179,6 +10340,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
/*nonnull*/false, tf_warning_or_error);
type = btype;
}
+ unsigned HOST_WIDE_INT j = 0;
unsigned int i = 0;
for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) != FIELD_DECL
@@ -10191,6 +10353,32 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
NULL_TREE);
if (REFERENCE_REF_P (tt))
tt = TREE_OPERAND (tt, 0);
+ if (pack != -1 && j >= (unsigned) pack)
+ {
+ if (j == (unsigned) pack)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ i++;
+ }
+ if (j < (unsigned) pack + eltscnt - (count - 1))
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 3 - i) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j + 1 - i);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = TREE_TYPE (tt);
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ SET_DECL_VALUE_EXPR (t, tt);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ else
+ DECL_HAS_VALUE_EXPR_P (t) = 0;
+ j++;
+ continue;
+ }
+ }
TREE_TYPE (v[i]) = TREE_TYPE (tt);
layout_decl (v[i], 0);
if (!processing_template_decl)
@@ -10199,7 +10387,26 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
i++;
+ j++;
}
+ if (pack != -1 && j == (unsigned) pack)
+ {
+ gcc_checking_assert (eltscnt == count - 1);
+ packv = make_tree_vec (2);
+ }
+ }
+ done:
+ if (packv)
+ {
+ gcc_checking_assert (pack != -1);
+ TREE_VEC_ELT (packv, 0) = decl;
+ TREE_VEC_ELT (packv, 1) = size_int (pack);
+ SET_DECL_VALUE_EXPR (v[pack], packv);
+ DECL_HAS_VALUE_EXPR_P (v[pack]) = 1;
+ DECL_IGNORED_P (v[pack]) = 1;
+ if (!processing_template_decl)
+ for (unsigned int i = 0; i < TREE_VEC_LENGTH (packv) - 2U; ++i)
+ pushdecl (TREE_VEC_ELT (packv, 2 + i));
}
if (processing_template_decl)
{
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index a8c54c7..743fd74 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -14672,13 +14672,23 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
tree v = DECL_VALUE_EXPR (range_decl);
/* For decomposition declaration get all of the corresponding
declarations out of the way. */
- if (TREE_CODE (v) == ARRAY_REF
- && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ if ((TREE_CODE (v) == ARRAY_REF
+ && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ || (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
{
tree d = range_decl;
- range_decl = TREE_OPERAND (v, 0);
decomp = &decomp_d;
- decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+ if (TREE_CODE (v) == ARRAY_REF)
+ {
+ range_decl = TREE_OPERAND (v, 0);
+ decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+ }
+ else
+ {
+ range_decl = TREE_VEC_ELT (v, 0);
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ }
decomp->decl = d;
bool seen_name_independent_decl = false;
for (unsigned int i = 0; i < decomp->count;
@@ -16843,7 +16853,7 @@ cp_parser_simple_declaration (cp_parser* parser,
}
/* Helper of cp_parser_simple_declaration, parse a decomposition declaration.
- decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
+ decl-specifier-seq ref-qualifier [opt] [ sb-identifier-list ]
initializer ; */
static tree
@@ -16856,21 +16866,45 @@ cp_parser_decomposition_declaration (cp_parser *parser,
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
- /* Parse the identifier-list. */
+ /* Parse the sb-identifier-list. */
auto_vec<cp_expr, 10> v;
bool attr_diagnosed = false;
int first_attr = -1;
+ int pack = -1;
unsigned int cnt = 0;
if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
while (true)
{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ location_t elloc = cp_lexer_peek_token (parser->lexer)->location;
+ if (!processing_template_decl)
+ error_at (elloc, "structured binding pack outside of template");
+ else if (pack != -1)
+ error_at (elloc,
+ "multiple packs in structured binding declaration");
+ else
+ {
+ if (keyword == RID_MAX
+ && cxx_dialect >= cxx17
+ && cxx_dialect < cxx26)
+ pedwarn (elloc, OPT_Wc__26_extensions,
+ "structured binding packs only available with "
+ "%<-std=c++2c%> or %<-std=gnu++2c%>");
+ pack = cnt;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ }
cp_expr e = cp_parser_identifier (parser);
if (e.get_value () == error_mark_node)
break;
tree attr = NULL_TREE;
if (cp_next_tokens_can_be_std_attribute_p (parser))
{
- if (cxx_dialect >= cxx17 && cxx_dialect < cxx26 && !attr_diagnosed)
+ if (keyword == RID_MAX
+ && cxx_dialect >= cxx17
+ && cxx_dialect < cxx26
+ && !attr_diagnosed)
{
pedwarn (cp_lexer_peek_token (parser->lexer)->location,
OPT_Wc__26_extensions,
@@ -16931,7 +16965,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
&pushed_scope);
tree orig_decl = decl;
- unsigned int i;
+ unsigned int i, j;
cp_expr e;
cp_decl_specifier_seq decl_specs;
clear_decl_specs (&decl_specs);
@@ -16939,6 +16973,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
if (decl_specifiers->storage_class == sc_static)
decl_specs.storage_class = sc_static;
tree prev = decl;
+ j = 0;
FOR_EACH_VEC_ELT (v, i, e)
{
if (i == 0)
@@ -16969,9 +17004,22 @@ cp_parser_decomposition_declaration (cp_parser *parser,
prev = decl2;
DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl);
DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl);
+ if (j == (unsigned) pack)
+ {
+ tree dtype = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (dtype) = decl2;
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+ SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+ tree type = cxx_make_type (TYPE_PACK_EXPANSION);
+ PACK_EXPANSION_PATTERN (type) = dtype;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ PACK_EXPANSION_PARAMETER_PACKS (type) = decl2;
+ TREE_TYPE (decl2) = type;
+ }
}
if (elt_pushed_scope)
pop_scope (elt_pushed_scope);
+ ++j;
}
if (v.is_empty ())
@@ -46300,6 +46348,14 @@ cp_convert_omp_range_for (tree &this_pre_body, tree &sl,
decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
decomp->decl = decl;
}
+ else if (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+ {
+ d = TREE_VEC_ELT (v, 0);
+ decomp = &decomp_d;
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ decomp->decl = decl;
+ }
}
do_range_for_auto_deduction (d, init, decomp);
}
@@ -46423,6 +46479,15 @@ cp_convert_omp_range_for (tree &this_pre_body, tree &sl,
decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
decomp->decl = d;
}
+ else if (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+ {
+ tree d = orig_decl;
+ orig_decl = TREE_VEC_ELT (v, 0);
+ decomp = &decomp_d;
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ decomp->decl = d;
+ }
}
tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index acfeb81..b6b13ed 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13981,9 +13981,30 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
else if (is_capture_proxy (parm_pack))
{
arg_pack = retrieve_local_specialization (parm_pack);
+ if (DECL_DECOMPOSITION_P (arg_pack))
+ {
+ orig_arg = arg_pack;
+ goto expand_sb_pack;
+ }
if (DECL_PACK_P (arg_pack))
arg_pack = NULL_TREE;
}
+ else if (DECL_DECOMPOSITION_P (parm_pack))
+ {
+ orig_arg = retrieve_local_specialization (parm_pack);
+ expand_sb_pack:
+ gcc_assert (DECL_DECOMPOSITION_P (orig_arg));
+ if (TREE_TYPE (orig_arg) == error_mark_node)
+ return error_mark_node;
+ gcc_assert (DECL_HAS_VALUE_EXPR_P (orig_arg));
+ arg_pack = DECL_VALUE_EXPR (orig_arg);
+ tree vec = make_tree_vec (TREE_VEC_LENGTH (arg_pack) - 2);
+ if (TREE_VEC_LENGTH (vec))
+ memcpy (TREE_VEC_BEGIN (vec), &TREE_VEC_ELT (arg_pack, 2),
+ TREE_VEC_LENGTH (vec) * sizeof (tree));
+ arg_pack = make_node (NONTYPE_ARGUMENT_PACK);
+ ARGUMENT_PACK_ARGS (arg_pack) = vec;
+ }
else
{
int idx;
@@ -13996,7 +14017,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
arg_pack = NULL_TREE;
}
- orig_arg = arg_pack;
+ if (orig_arg == NULL_TREE)
+ orig_arg = arg_pack;
if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
@@ -14011,8 +14033,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (arg_pack)
{
- int my_len =
- TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
+ int my_len
+ = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
/* Don't bother trying to do a partial substitution with
incomplete packs; we'll try again after deduction. */
@@ -14176,8 +14198,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/* Update the corresponding argument. */
if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
- TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) =
- TREE_TYPE (pack);
+ TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx)
+ = TREE_TYPE (pack);
else
TREE_VEC_ELT (args, idx) = TREE_TYPE (pack);
}
@@ -15921,7 +15943,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain,
tsubst_flags_t tcomplain = complain;
if (VAR_P (t))
tcomplain |= tf_tst_ok;
- type = tsubst (type, args, tcomplain, in_decl);
+ if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+ type = NULL_TREE;
+ else
+ type = tsubst (type, args, tcomplain, in_decl);
/* Substituting the type might have recursively instantiated this
same alias (c++/86171). */
if (use_spec_table && gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl)
@@ -15938,6 +15963,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain,
{
DECL_INITIALIZED_P (r) = 0;
DECL_TEMPLATE_INSTANTIATED (r) = 0;
+ if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+ {
+ tree dtype = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (dtype) = r;
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+ SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+ type = cxx_make_type (TYPE_PACK_EXPANSION);
+ PACK_EXPANSION_PATTERN (type) = dtype;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ PACK_EXPANSION_PARAMETER_PACKS (type) = r;
+ }
if (TREE_CODE (type) == FUNCTION_TYPE)
{
/* It may seem that this case cannot occur, since:
@@ -18555,13 +18591,17 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv,
if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
{
tree v = DECL_VALUE_EXPR (decl);
- if (TREE_CODE (v) == ARRAY_REF
- && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ if ((TREE_CODE (v) == ARRAY_REF
+ && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ || (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
{
+ v = (TREE_CODE (v) == ARRAY_REF
+ ? TREE_OPERAND (v, 0) : TREE_VEC_ELT (v, 0));
cp_decomp decomp_d = { NULL_TREE, 0 };
- tree d = tsubst_decl (TREE_OPERAND (v, 0), args, complain);
+ tree d = tsubst_decl (v, args, complain);
maybe_push_decl (d);
- d = tsubst_decomp_names (d, TREE_OPERAND (v, 0), args, complain,
+ d = tsubst_decomp_names (d, v, args, complain,
in_decl, &decomp_d);
decomp = true;
if (d == error_mark_node)
@@ -21220,7 +21260,28 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++c_inhibit_evaluation_warnings;
/* We only want to compute the number of arguments. */
if (PACK_EXPANSION_P (op))
- expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+ {
+ expanded = NULL_TREE;
+ if (DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (op);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ if (TREE_CODE (d) == TREE_VEC)
+ {
+ tree b = TREE_VEC_ELT (d, 0);
+ if (!type_dependent_expression_p_push (b))
+ {
+ expanded = void_node;
+ len = TREE_VEC_LENGTH (d) - 2;
+ }
+ }
+ }
+ }
+ if (!expanded)
+ expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+ }
else
expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op),
args, complain, in_decl);
@@ -29050,6 +29111,24 @@ value_dependent_expression_p (tree expression)
case SIZEOF_EXPR:
if (SIZEOF_EXPR_TYPE_P (expression))
return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
+ if (tree p = TREE_OPERAND (expression, 0))
+ if (PACK_EXPANSION_P (p)
+ && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (p)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (p);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ /* [temp.dep.constexpr]/4:
+ Expressions of the following form are value-dependent:
+ sizeof ... ( identifier )
+ unless the identifier is a structured binding pack whose
+ initializer is not dependent. */
+ if (TREE_CODE (d) == TREE_VEC
+ && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+ return false;
+ }
+ }
/* FALLTHRU */
case ALIGNOF_EXPR:
case TYPEID_EXPR:
@@ -29563,6 +29642,22 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
tree op = TREE_OPERAND (*tp, 0);
if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
op = TREE_TYPE (op);
+ else if (code == SIZEOF_EXPR
+ && PACK_EXPANSION_P (op)
+ && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (op);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ if (TREE_CODE (d) == TREE_VEC
+ && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ }
+ }
if (TYPE_P (op))
{
if (dependent_type_p (op))
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index c723a07..ee9c048 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -8460,14 +8460,10 @@ simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
if (GET_CODE (op) == SUBREG
|| GET_CODE (op) == CONCAT
- || GET_MODE (op) == VOIDmode)
- return NULL_RTX;
-
- if (MODE_COMPOSITE_P (outermode)
- && (CONST_SCALAR_INT_P (op)
- || CONST_DOUBLE_AS_FLOAT_P (op)
- || CONST_FIXED_P (op)
- || GET_CODE (op) == CONST_VECTOR))
+ || CONST_SCALAR_INT_P (op)
+ || CONST_DOUBLE_AS_FLOAT_P (op)
+ || CONST_FIXED_P (op)
+ || GET_CODE (op) == CONST_VECTOR)
return NULL_RTX;
if (validate_subreg (outermode, innermode, op, byte))
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp13.C b/gcc/testsuite/g++.dg/cpp26/decomp13.C
new file mode 100644
index 0000000..d01590f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp13.C
@@ -0,0 +1,52 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct S { int a, b, c, d; };
+struct T {
+ int a[5];
+ template <int I> int &get () { return a[I]; }
+};
+
+template<> struct std::tuple_size<T> { static const int value = 5; };
+template<int I> struct std::tuple_element<I,T> { using type = int; };
+
+template <int N>
+void
+foo ()
+{
+ auto [a, ...b, c] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [...d] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [...e, f, ...g, h] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "multiple packs in structured binding declaration" "" { target *-*-* } .-2 }
+ auto [i, j, k, l, ...m, n] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "6 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'S' decomposes into 4 elements" "" { target *-*-* } .-3 }
+ auto [o, ...p, q, r, s] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [t, u, v, w, x, ...y, z] = T (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "7 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'T' decomposes into 5 elements" "" { target *-*-* } .-3 }
+ int aa[] = { 1, 2, 3 };
+ const auto & [ab, ...ac, ad, ae, af] = aa; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "5 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'const int \\\[3\\\]' decomposes into 3 elements" "" { target *-*-* } .-3 }
+}
+
+void
+bar ()
+{
+ auto [a, ...b, c, d] = S (); // { dg-error "structured binding pack outside of template" }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp14.C b/gcc/testsuite/g++.dg/cpp26/decomp14.C
new file mode 100644
index 0000000..f626ec9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp14.C
@@ -0,0 +1,474 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ int a; long long b; short c;
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ short c; int a; long long b;
+ template <int I>
+ typename std::tuple_element<I, T>::type &get ();
+ template <int I>
+ typename std::tuple_element<I, const T>::type &get () const;
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+ return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <int N>
+size_t
+foo ()
+{
+ S s = S { 1, 2, 3 };
+ auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (sa), int>::value, "");
+ static_assert (same_type <decltype (sb), long long>::value, "");
+ static_assert (same_type <decltype (sc), short>::value, "");
+ auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ constexpr size_t ses = sizeof... (se);
+ static_assert (sizeof... (se) == 2, "");
+ static_assert (same_type <decltype (sd), int>::value, "");
+ static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sf) == 2, "");
+ static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sg), const short>::value, "");
+ auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sk) == 0, "");
+ static_assert (same_type <decltype (sh), int>::value, "");
+ static_assert (same_type <decltype (si), long long>::value, "");
+ static_assert (same_type <decltype (sj), short>::value, "");
+ auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sm) == 1, "");
+ static_assert (same_type <decltype (sl), int>::value, "");
+ static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sn), short>::value, "");
+ auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (so) == 3, "");
+ static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sp) == 0, "");
+ static_assert (same_type <decltype (sq), int>::value, "");
+ static_assert (same_type <decltype (sr), long long>::value, "");
+ static_assert (same_type <decltype (ss), short>::value, "");
+ auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (su) == 0, "");
+ static_assert (same_type <decltype (st), int>::value, "");
+ static_assert (same_type <decltype (sv), long long>::value, "");
+ static_assert (same_type <decltype (sw), short>::value, "");
+ if (sa != 1 || sb != 2 || sc != 3
+ || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sh != 1 || si != 2 || sj != 3
+ || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sq != 1 || sr != 2 || ss != 3
+ || st != 1 || sv != 2 || sw != 3
+ || sum (se...) != 5
+ || sum <decltype (se)...> (se...) != 5
+ || sum (square (square (se))...) != 97
+ || sum (sf...) != 3
+ || sum (sk...) != 0
+ || sum (sm...) != 2
+ || sum (so...) != 6
+ || sum <decltype (so)...> (so...) != 6
+ || sum (square (so)...) != 14
+ || sum (sp...) != 0
+ || sum (su...) != 0
+ || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ int i = 0;
+ for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sy) == 2, "");
+ static_assert (same_type <decltype (sx), int>::value, "");
+ static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn1 ();
+ auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn5 ();
+ auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn9 ();
+ auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn13 ();
+ auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sz) == 3, "");
+ static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (sz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn ();
+ ++i;
+ }
+ if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ {
+ static_assert (sizeof... (sx) == 2, "");
+ static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy), short>::value, "");
+ if (sum (sx...) != 3 || sy != 3)
+ __builtin_abort ();
+ }
+ else
+ __builtin_abort ();
+ T t = T { 3, 1, 2 };
+ auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (ta), int>::value, "");
+ static_assert (same_type <decltype (tb), long long>::value, "");
+ static_assert (same_type <decltype (tc), short>::value, "");
+ auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (te) == 2, "");
+ static_assert (same_type <decltype (td), int>::value, "");
+ static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tf) == 2, "");
+ static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tg), short>::value, "");
+ const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tk) == 0, "");
+ static_assert (same_type <decltype (th), const int>::value, "");
+ static_assert (same_type <decltype (ti), const long long>::value, "");
+ static_assert (same_type <decltype (tj), const short>::value, "");
+ auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tm) == 1, "");
+ static_assert (same_type <decltype (tl), int>::value, "");
+ static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tn), short>::value, "");
+ auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (to) == 3, "");
+ static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tp) == 0, "");
+ static_assert (same_type <decltype (tq), int>::value, "");
+ static_assert (same_type <decltype (tr), long long>::value, "");
+ static_assert (same_type <decltype (ts), short>::value, "");
+ auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tu) == 0, "");
+ static_assert (same_type <decltype (tt), int>::value, "");
+ static_assert (same_type <decltype (tv), long long>::value, "");
+ static_assert (same_type <decltype (tw), short>::value, "");
+ if (ta != 1 || tb != 2 || tc != 3
+ || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || th != 1 || ti != 2 || tj != 3
+ || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tq != 1 || tr != 2 || ts != 3
+ || tt != 1 || tv != 2 || tw != 3
+ || sum (te...) != 5
+ || sum <decltype (te)...> (te...) != 5
+ || sum (square (square (te))...) != 97
+ || sum (tf...) != 3
+ || sum (tk...) != 0
+ || sum (tm...) != 2
+ || sum (to...) != 6
+ || sum <decltype (to)...> (to...) != 6
+ || sum (square (to)...) != 14
+ || sum (tp...) != 0
+ || sum (tu...) != 0
+ || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+ i = 0;
+ for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ty) == 2, "");
+ static_assert (same_type <decltype (tx), int>::value, "");
+ static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn1 ();
+ auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn5 ();
+ auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn9 ();
+ auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn13 ();
+ auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tz) == 3, "");
+ static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (tz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+ fn ();
+ ++i;
+ }
+ if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ {
+ static_assert (sizeof... (tx) == 2, "");
+ static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty), short>::value, "");
+ if (sum (tx...) != 3 || ty != 3)
+ __builtin_abort ();
+ }
+ int a[3] = { 1, 2, 3 };
+ auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (aa), int>::value, "");
+ static_assert (same_type <decltype (ab), int>::value, "");
+ static_assert (same_type <decltype (ac), int>::value, "");
+ auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ae) == 2, "");
+ static_assert (same_type <decltype (ad), int>::value, "");
+ static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (af) == 2, "");
+ static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ag), int>::value, "");
+ auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ak) == 0, "");
+ static_assert (same_type <decltype (ah), int>::value, "");
+ static_assert (same_type <decltype (ai), int>::value, "");
+ static_assert (same_type <decltype (aj), int>::value, "");
+ auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (am) == 1, "");
+ static_assert (same_type <decltype (al), int>::value, "");
+ static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (an), int>::value, "");
+ const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ao) == 3, "");
+ static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ap) == 0, "");
+ static_assert (same_type <decltype (aq), int>::value, "");
+ static_assert (same_type <decltype (ar), int>::value, "");
+ static_assert (same_type <decltype (as), int>::value, "");
+ auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (au) == 0, "");
+ static_assert (same_type <decltype (at), int>::value, "");
+ static_assert (same_type <decltype (av), int>::value, "");
+ static_assert (same_type <decltype (aw), int>::value, "");
+ if (aa != 1 || ab != 2 || ac != 3
+ || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ah != 1 || ai != 2 || aj != 3
+ || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || aq != 1 || ar != 2 || as != 3
+ || at != 1 || av != 2 || aw != 3
+ || sum (ae...) != 5
+ || sum <decltype (ae)...> (ae...) != 5
+ || sum (square (square (ae))...) != 97
+ || sum (af...) != 3
+ || sum (ak...) != 0
+ || sum (am...) != 2
+ || sum (ao...) != 6
+ || sum <decltype (ao)...> (ao...) != 6
+ || sum (square (ao)...) != 14
+ || sum (ap...) != 0
+ || sum (au...) != 0
+ || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ return ses;
+}
+
+int
+main ()
+{
+ if (foo <0> () != 2)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp15.C b/gcc/testsuite/g++.dg/cpp26/decomp15.C
new file mode 100644
index 0000000..9bb55b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp15.C
@@ -0,0 +1,474 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ int a; long long b; short c;
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ short c; int a; long long b;
+ template <int I>
+ typename std::tuple_element<I, T>::type &get ();
+ template <int I>
+ typename std::tuple_element<I, const T>::type &get () const;
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+ return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <typename S, typename T, typename U>
+size_t
+foo ()
+{
+ S s = S { 1, 2, 3 };
+ auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (sa), int>::value, "");
+ static_assert (same_type <decltype (sb), long long>::value, "");
+ static_assert (same_type <decltype (sc), short>::value, "");
+ auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (se) == 2, "");
+ static_assert (same_type <decltype (sd), int>::value, "");
+ static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sf) == 2, "");
+ static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sg), const short>::value, "");
+ auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sk) == 0, "");
+ static_assert (same_type <decltype (sh), int>::value, "");
+ static_assert (same_type <decltype (si), long long>::value, "");
+ static_assert (same_type <decltype (sj), short>::value, "");
+ auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sm) == 1, "");
+ static_assert (same_type <decltype (sl), int>::value, "");
+ static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sn), short>::value, "");
+ auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (so) == 3, "");
+ static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sp) == 0, "");
+ static_assert (same_type <decltype (sq), int>::value, "");
+ static_assert (same_type <decltype (sr), long long>::value, "");
+ static_assert (same_type <decltype (ss), short>::value, "");
+ auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (su) == 0, "");
+ static_assert (same_type <decltype (st), int>::value, "");
+ static_assert (same_type <decltype (sv), long long>::value, "");
+ static_assert (same_type <decltype (sw), short>::value, "");
+ if (sa != 1 || sb != 2 || sc != 3
+ || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sh != 1 || si != 2 || sj != 3
+ || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sq != 1 || sr != 2 || ss != 3
+ || st != 1 || sv != 2 || sw != 3
+ || sum (se...) != 5
+ || sum <decltype (se)...> (se...) != 5
+ || sum (square (square (se))...) != 97
+ || sum (sf...) != 3
+ || sum (sk...) != 0
+ || sum (sm...) != 2
+ || sum (so...) != 6
+ || sum <decltype (so)...> (so...) != 6
+ || sum (square (so)...) != 14
+ || sum (sp...) != 0
+ || sum (su...) != 0
+ || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ int i = 0;
+ for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sy) == 2, "");
+ static_assert (same_type <decltype (sx), int>::value, "");
+ static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn1 ();
+ auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn5 ();
+ auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn9 ();
+ auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn13 ();
+ auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sz) == 3, "");
+ static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (sz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn ();
+ ++i;
+ }
+ if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ {
+ static_assert (sizeof... (sx) == 2, "");
+ static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy), short>::value, "");
+ if (sum (sx...) != 3 || sy != 3)
+ __builtin_abort ();
+ }
+ else
+ __builtin_abort ();
+ T t = T { 3, 1, 2 };
+ auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (ta), int>::value, "");
+ static_assert (same_type <decltype (tb), long long>::value, "");
+ static_assert (same_type <decltype (tc), short>::value, "");
+ auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (te) == 2, "");
+ static_assert (same_type <decltype (td), int>::value, "");
+ static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tf) == 2, "");
+ static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tg), short>::value, "");
+ const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tk) == 0, "");
+ static_assert (same_type <decltype (th), const int>::value, "");
+ static_assert (same_type <decltype (ti), const long long>::value, "");
+ static_assert (same_type <decltype (tj), const short>::value, "");
+ auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tm) == 1, "");
+ static_assert (same_type <decltype (tl), int>::value, "");
+ static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tn), short>::value, "");
+ auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (to) == 3, "");
+ constexpr size_t tos = sizeof... (to);
+ static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tp) == 0, "");
+ static_assert (same_type <decltype (tq), int>::value, "");
+ static_assert (same_type <decltype (tr), long long>::value, "");
+ static_assert (same_type <decltype (ts), short>::value, "");
+ auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tu) == 0, "");
+ static_assert (same_type <decltype (tt), int>::value, "");
+ static_assert (same_type <decltype (tv), long long>::value, "");
+ static_assert (same_type <decltype (tw), short>::value, "");
+ if (ta != 1 || tb != 2 || tc != 3
+ || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || th != 1 || ti != 2 || tj != 3
+ || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tq != 1 || tr != 2 || ts != 3
+ || tt != 1 || tv != 2 || tw != 3
+ || sum (te...) != 5
+ || sum <decltype (te)...> (te...) != 5
+ || sum (square (square (te))...) != 97
+ || sum (tf...) != 3
+ || sum (tk...) != 0
+ || sum (tm...) != 2
+ || sum (to...) != 6
+ || sum <decltype (to)...> (to...) != 6
+ || sum (square (to)...) != 14
+ || sum (tp...) != 0
+ || sum (tu...) != 0
+ || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+ i = 0;
+ for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ty) == 2, "");
+ static_assert (same_type <decltype (tx), int>::value, "");
+ static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn1 ();
+ auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn5 ();
+ auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn9 ();
+ auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn13 ();
+ auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tz) == 3, "");
+ static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (tz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+ fn ();
+ ++i;
+ }
+ if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ {
+ static_assert (sizeof... (tx) == 2, "");
+ static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty), short>::value, "");
+ if (sum (tx...) != 3 || ty != 3)
+ __builtin_abort ();
+ }
+ U a[3] = { 1, 2, 3 };
+ auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (aa), int>::value, "");
+ static_assert (same_type <decltype (ab), int>::value, "");
+ static_assert (same_type <decltype (ac), int>::value, "");
+ auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ae) == 2, "");
+ static_assert (same_type <decltype (ad), int>::value, "");
+ static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (af) == 2, "");
+ static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ag), int>::value, "");
+ auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ak) == 0, "");
+ static_assert (same_type <decltype (ah), int>::value, "");
+ static_assert (same_type <decltype (ai), int>::value, "");
+ static_assert (same_type <decltype (aj), int>::value, "");
+ auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (am) == 1, "");
+ static_assert (same_type <decltype (al), int>::value, "");
+ static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (an), int>::value, "");
+ const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ao) == 3, "");
+ static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ap) == 0, "");
+ static_assert (same_type <decltype (aq), int>::value, "");
+ static_assert (same_type <decltype (ar), int>::value, "");
+ static_assert (same_type <decltype (as), int>::value, "");
+ auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (au) == 0, "");
+ static_assert (same_type <decltype (at), int>::value, "");
+ static_assert (same_type <decltype (av), int>::value, "");
+ static_assert (same_type <decltype (aw), int>::value, "");
+ if (aa != 1 || ab != 2 || ac != 3
+ || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ah != 1 || ai != 2 || aj != 3
+ || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || aq != 1 || ar != 2 || as != 3
+ || at != 1 || av != 2 || aw != 3
+ || sum (ae...) != 5
+ || sum <decltype (ae)...> (ae...) != 5
+ || sum (square (square (ae))...) != 97
+ || sum (af...) != 3
+ || sum (ak...) != 0
+ || sum (am...) != 2
+ || sum (ao...) != 6
+ || sum <decltype (ao)...> (ao...) != 6
+ || sum (square (ao)...) != 14
+ || sum (ap...) != 0
+ || sum (au...) != 0
+ || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ return tos;
+}
+
+int
+main ()
+{
+ if (foo <S, T, int> () != 3)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp16.C b/gcc/testsuite/g++.dg/cpp26/decomp16.C
new file mode 100644
index 0000000..548f9af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp16.C
@@ -0,0 +1,240 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (va) == 16, "");
+ static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vc) == 13, "");
+ static_assert (same_type <decltype (vb), int>::value, "");
+ static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vd), int>::value, "");
+ static_assert (same_type <decltype (ve), int>::value, "");
+ auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vj) == 12, "");
+ static_assert (same_type <decltype (vf), int>::value, "");
+ static_assert (same_type <decltype (vg), int>::value, "");
+ static_assert (same_type <decltype (vh), int>::value, "");
+ static_assert (same_type <decltype (vi), int>::value, "");
+ static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (va...) != 8 * 17
+ || sum (square (va)...) != 1496
+ || vb != 1
+ || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (vc...) != 15 * 7 - 1
+ || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+ || vd != 15 || ve != 16
+ || vf != 1 || vg != 2 || vh != 3 || vi != 4
+ || sum (vj...) != 8 * 17 - 10
+ || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ V v2[3] = { v, v + 1, v + 2 };
+ int i = 0;
+ for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vl) == 14, "");
+ static_assert (same_type <decltype (vk), int>::value, "");
+ static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vm), int>::value, "");
+ if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+ __builtin_abort ();
+ ++i;
+ }
+ _Complex double c = 1.0 + 2.0i;
+ auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ca) == 2, "");
+ static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cc) == 0, "");
+ static_assert (same_type <decltype (cb), double>::value, "");
+ static_assert (same_type <decltype (cd), double>::value, "");
+ auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cf) == 1, "");
+ static_assert (same_type <decltype (ce), double>::value, "");
+ static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cg) == 1, "");
+ static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ch), double>::value, "");
+ if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (ca...) != 3.0
+ || sum <decltype (ca)...> (ca...) != 3.0
+ || sum (square (square (square (ca)))...) != 257.0
+ || cb != 1.0 || cd != 2.0
+ || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cf...) != 2.0
+ || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cg...) != 1.0
+ || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ _Complex float c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+ i = 0;
+ for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ci) == 2, "");
+ static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (ci...) != i * 2 + 3.0f)
+ __builtin_abort ();
+ ++i;
+ }
+}
+
+template <typename V, typename C, typename D>
+void
+bar ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (va) == 16, "");
+ static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vc) == 13, "");
+ static_assert (same_type <decltype (vb), int>::value, "");
+ static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vd), int>::value, "");
+ static_assert (same_type <decltype (ve), int>::value, "");
+ auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vj) == 12, "");
+ static_assert (same_type <decltype (vf), int>::value, "");
+ static_assert (same_type <decltype (vg), int>::value, "");
+ static_assert (same_type <decltype (vh), int>::value, "");
+ static_assert (same_type <decltype (vi), int>::value, "");
+ static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (va...) != 8 * 17
+ || vb != 1
+ || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (vc...) != 15 * 7 - 1
+ || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+ || vd != 15 || ve != 16
+ || vf != 1 || vg != 2 || vh != 3 || vi != 4
+ || sum (vj...) != 8 * 17 - 10
+ || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ V v2[3] = { v, v + 1, v + 2 };
+ int i = 0;
+ for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vl) == 14, "");
+ static_assert (same_type <decltype (vk), int>::value, "");
+ static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vm), int>::value, "");
+ if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+ __builtin_abort ();
+ ++i;
+ }
+ C c = 1.0 + 2.0i;
+ auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ca) == 2, "");
+ static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cc) == 0, "");
+ static_assert (same_type <decltype (cb), double>::value, "");
+ static_assert (same_type <decltype (cd), double>::value, "");
+ auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cf) == 1, "");
+ static_assert (same_type <decltype (ce), double>::value, "");
+ static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cg) == 1, "");
+ static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ch), double>::value, "");
+ if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (ca...) != 3.0
+ || sum <decltype (ca)...> (ca...) != 3.0
+ || cb != 1.0 || cd != 2.0
+ || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cf...) != 2.0
+ || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cg...) != 1.0
+ || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ D c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+ i = 0;
+ for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ci) == 2, "");
+ static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (ci...) != i * 2 + 3.0f)
+ __builtin_abort ();
+ ++i;
+ }
+}
+
+int
+main ()
+{
+ foo <0> ();
+ bar <V, _Complex double, _Complex float> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp17.C b/gcc/testsuite/g++.dg/cpp26/decomp17.C
new file mode 100644
index 0000000..49ad0e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp17.C
@@ -0,0 +1,28 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [va, vb, vc, vd, ...ve, vf, vg, vh, vi, vj, vk, vl, vm, vn, vo, vp, vq, vr] = v;
+ // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } .-1 }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
+ // { dg-error "18 names provided for structured binding" "" { target *-*-* } .-3 }
+ // { dg-message "while '__vector\\\(16\\\) int' decomposes into 16 elements" "" { target *-*-* } .-4 }
+ _Complex double c = 1.0 + 2.0i;
+ auto [...ca, cb, cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "4 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while '__complex__ double' decomposes into 2 elements" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+ foo <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp18.C b/gcc/testsuite/g++.dg/cpp26/decomp18.C
new file mode 100644
index 0000000..86b9bf4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp18.C
@@ -0,0 +1,109 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S { int a, b, c; };
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ int a[3];
+ template <int I>
+ int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline int
+foo ()
+{
+ static int a[4] = { N, N + 1, N + 2, N + 3 };
+ static auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+bar ()
+{
+ static S s = { N, N + 1, N + 2 };
+ static auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+baz ()
+{
+ static T t = { { N, N + 1, N + 2 } };
+ static auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ tc++;
+ return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+qux ()
+{
+ thread_local int a[4] = { N, N + 1, N + 2, N + 3 };
+ thread_local auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+freddy ()
+{
+ thread_local S s = { N, N + 1, N + 2 };
+ thread_local auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+corge ()
+{
+ thread_local T t = { { N, N + 1, N + 2 } };
+ thread_local auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ tc++;
+ return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+int
+main ()
+{
+ if (foo <2> () != 15 || foo <2> () != 16 || foo <2> () != 17
+ || foo <42> () != 175 || foo <42> () != 176
+ || bar <5> () != 19 || bar <5> () != 20 || bar <5> () != 21
+ || bar <18> () != 58 || bar <18> () != 59
+ || baz <3> () != 13 || baz <3> () != 14 || baz <3> () != 15
+ || baz <22> () != 70 || baz <22> () != 71)
+ __builtin_abort ();
+ if (qux <2> () != 15 || qux <2> () != 16 || qux <2> () != 17
+ || qux <42> () != 175 || qux <42> () != 176
+ || freddy <5> () != 19 || freddy <5> () != 20 || freddy <5> () != 21
+ || freddy <18> () != 58 || freddy <18> () != 59
+ || corge <3> () != 13 || corge <3> () != 14 || corge <3> () != 15
+ || corge <22> () != 70 || corge <22> () != 71)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp19.C b/gcc/testsuite/g++.dg/cpp26/decomp19.C
new file mode 100644
index 0000000..b4d97a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp19.C
@@ -0,0 +1,46 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ int a[3];
+ template <int I>
+ int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline void
+foo ()
+{
+ static T t = { { N, N + 1, N + 2 } };
+ static auto [ta, ...tb, tc] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+template <int N>
+inline void
+bar ()
+{
+ thread_local T t = { { N, N + 1, N + 2 } };
+ thread_local auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+ foo <0> ();
+ bar <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp20.C b/gcc/testsuite/g++.dg/cpp26/decomp20.C
new file mode 100644
index 0000000..5091e13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp20.C
@@ -0,0 +1,53 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+int x;
+struct T {
+ template <int I>
+ int &get () { return x; }
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 0; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+void
+foo ()
+{
+ int a[0] = {};
+ auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (aa) == 0, "");
+ S s = {};
+ auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sa) == 0, "");
+ T t = {};
+ auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ta) == 0, "");
+ if (auto [...sb] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ static_assert (sizeof... (sb) == 0, "");
+ else
+ __builtin_abort ();
+ if (auto [...tb] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ static_assert (sizeof... (tb) == 0, "");
+}
+
+int
+main ()
+{
+ foo <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp21.C b/gcc/testsuite/g++.dg/cpp26/decomp21.C
new file mode 100644
index 0000000..6baa8aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp21.C
@@ -0,0 +1,103 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+using size_t = decltype (sizeof 0);
+
+auto g () -> int (&)[4]
+{
+ static int a[4] = { 1, 2, 3, 4 };
+ return a;
+}
+
+template <size_t N>
+void
+h (int (&arr)[N])
+{
+ auto [a, ...b, c] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (b) == 2, "");
+ auto &[f, ...g, h] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (g) == 2, "");
+ if (&f != &arr[0] || &h != &arr[3]
+ || &g...[0] != &arr[1] || &g...[1] != &arr[2]) // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ auto &[...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof ... (e) == 4, "");
+ if (&e...[0] != &arr[0] || &e...[3] != &arr[3]) // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ __builtin_abort ();
+}
+
+struct C { int x, y, z; };
+
+template <class T>
+void
+now_i_know_my ()
+{
+ auto [a, b, c] = C (); // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ auto [d, ...e] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (e) == 2, "");
+ auto [...f, g] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (f) == 2, "");
+ auto [h, i, j, ...k] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (k) == 0, "");
+// auto [l, m, n, o, ...p] = C ();
+}
+
+auto foo () -> int (&)[2]
+{
+ static int a[2] = { 1, 2 };
+ return a;
+}
+
+template <class T>
+void
+bar ()
+{
+ auto [...a] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (a) == 2, "");
+ auto [b, c, ...d] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (d) == 0, "");
+}
+
+struct D { };
+
+void
+baz (...)
+{
+ __builtin_abort ();
+}
+
+template <typename T>
+void
+qux ()
+{
+ D arr[1] = {};
+ auto [...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ baz (e...);
+}
+
+int d;
+
+void
+baz (D)
+{
+ d = 1;
+}
+
+int
+main ()
+{
+ h (g ());
+ now_i_know_my <int> ();
+ bar <int> ();
+ qux <int> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
index cfc5f61..9284bc2 100644
--- a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
+++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
@@ -395,8 +395,8 @@
#ifndef __cpp_structured_bindings
# error "__cpp_structured_bindings"
-#elif __cpp_structured_bindings != 202403
-# error "__cpp_structured_bindings != 202403"
+#elif __cpp_structured_bindings != 202411
+# error "__cpp_structured_bindings != 202411"
#endif
#ifndef __cpp_template_template_args
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c
new file mode 100644
index 0000000..f80baf3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+struct vec_char_16
+{
+ unsigned char raw[2];
+};
+
+static inline struct vec_char_16
+Dup128VecFromValues(unsigned char t0, unsigned char t1)
+{
+ struct vec_char_16 result;
+ result.raw[0] = t0;
+ result.raw[1] = t1;
+ return result;
+}
+
+int f(unsigned char t0, unsigned char t1)
+{
+ struct vec_char_16 a = Dup128VecFromValues(t0, t1);
+ struct vec_char_16 b;
+ __builtin_memcpy(&b, &a, sizeof(a));
+ return b.raw[0] + b.raw[1];
+}
+
+/* Ideally we'd optimize this at FRE1 time but we only replace
+ the loads from b.raw[] with BIT_FIELD_REFs which get optimized
+ only later in the next FRE. */
+/* { dg-final { scan-tree-dump-not "MEM" "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c b/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c
new file mode 100644
index 0000000..ad8600f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c
@@ -0,0 +1,27 @@
+#pragma GCC target "+sme2"
+
+void f1() __arm_streaming_compatible {}
+void f2() __arm_streaming {}
+void f3() __arm_in("za") {}
+void f4() __arm_out("za") {}
+void f5() __arm_inout("za") {}
+void f6() __arm_in("zt0") {}
+void f7() __arm_out("zt0") {}
+void f8() __arm_inout("zt0") {}
+
+__arm_locally_streaming void g1() {}
+__arm_new("za") void g2() {}
+__arm_new("zt0") void g3() {}
+
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf1\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf2\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf3\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf4\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf5\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf6\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf7\n} } } */
+/* { dg-final { scan-assembler {\t\.variant_pcs\tf8\n} } } */
+
+/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg1\n} } } */
+/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg2\n} } } */
+/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg3\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c
new file mode 100644
index 0000000..9ca0938
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+typedef int __attribute__((vector_size(8))) v2si;
+typedef struct { int x; int y; } A;
+void bar(A a);
+void foo()
+{
+ A a;
+ *(v2si *)&a = (v2si){0, (int)svcntd_pat(SV_ALL)};
+ bar(a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr90579.c b/gcc/testsuite/gcc.target/i386/pr90579.c
index ab48a44..bd2fd33 100644
--- a/gcc/testsuite/gcc.target/i386/pr90579.c
+++ b/gcc/testsuite/gcc.target/i386/pr90579.c
@@ -16,8 +16,5 @@ loop (int k, double x)
return t;
}
-/* Verify we end up with scalar loads from r for the final sum. */
-/* { dg-final { scan-assembler "vaddsd\tr\\\+40" } } */
-/* { dg-final { scan-assembler "vaddsd\tr\\\+32" } } */
-/* { dg-final { scan-assembler "vaddsd\tr\\\+24" } } */
-/* { dg-final { scan-assembler "vaddsd\tr\\\+16" } } */
+/* Verify we end up with no loads from r. */
+/* { dg-final { scan-assembler-not "v\[ma\]\[^\t \]+\tr" } } */
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 00315d1..1c113f8 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5633,6 +5633,28 @@ visit_nary_op (tree lhs, gassign *stmt)
}
}
break;
+ case BIT_FIELD_REF:
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+ {
+ tree op0 = TREE_OPERAND (rhs1, 0);
+ gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0));
+ if (ass
+ && !gimple_has_volatile_ops (ass)
+ && vn_get_stmt_kind (ass) == VN_REFERENCE)
+ {
+ tree last_vuse = gimple_vuse (ass);
+ tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1),
+ gimple_assign_rhs1 (ass),
+ TREE_OPERAND (rhs1, 1), TREE_OPERAND (rhs1, 2));
+ tree result = vn_reference_lookup (op, gimple_vuse (ass),
+ default_vn_walk_kind,
+ NULL, true, &last_vuse);
+ if (result
+ && useless_type_conversion_p (type, TREE_TYPE (result)))
+ return set_ssa_val_to (lhs, result);
+ }
+ }
+ break;
case TRUNC_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;