Bug 114457 - [C++26] P2795R5 - Erroneous behavior for uninitialized reads
Summary: [C++26] P2795R5 - Erroneous behavior for uninitialized reads
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks: c++26-core
  Show dependency treegraph
 
Reported: 2024-03-25 11:09 UTC by Jakub Jelinek
Modified: 2025-10-20 19:29 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-03-25 00:00:00


Attachments
gcc16-pr114457-wip.patch (11.33 KB, patch)
2025-09-11 13:49 UTC, Jakub Jelinek
Details | Diff
gcc16-pr114457-wip.patch (13.78 KB, patch)
2025-09-12 17:30 UTC, Jakub Jelinek
Details | Diff
gcc16-pr114457-wip.patch (17.60 KB, patch)
2025-09-16 16:51 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2024-03-25 11:09:31 UTC
See <https://wg21.link/P2795R5>.
Comment 1 Andrew Pinski 2024-03-25 17:54:33 UTC
.
Comment 2 Andrew Pinski 2024-03-25 18:04:34 UTC
This might require both gimple and rtl changes.
Well
Comment 3 Andrew Pinski 2024-03-25 23:59:41 UTC
(In reply to Andrew Pinski from comment #2)
Well RTL might be already done via init-regs (but there was some movement on removing that), see PR 61810 .
Comment 4 Sam James 2025-09-02 20:54:59 UTC
ML discussion: https://inbox.sourceware.org/gcc/aLVlJKBqfrLjwsIO@tucnak/
Comment 5 Jakub Jelinek 2025-09-11 13:49:19 UTC
Created attachment 62368 [details]
gcc16-pr114457-wip.patch

Untested WIP progress, which compared to the last gcc-patches posted one can now
handle also forward gotos across vacuous initializations for C++26 (but it can
still mess up -Wimplicit-fallthrough* handling).
Next steps are handling of backward gotos across vacuous initializations, then
switch jumps to case labels across vacuous initializations and finally trying to
deal with it for -Wimplicit-fallthrough*.
Comment 6 Jakub Jelinek 2025-09-12 17:30:20 UTC
Created attachment 62375 [details]
gcc16-pr114457-wip.patch

Updated patch.  This handles both forward and backward gotos as well as switch to case/default label jumps, but still want to debug some details in there and turn:
struct S { int a, b, c; };

int
foo (int x)
{
  int r = 0;
  if (x == 1)
    goto l1;
  S s1;
  if (x == 2)
    goto l1;
  S s2;
  {
    S s10;
    if (x == 12)
      goto l1;
    s10.a = 1;
    r += s10.a;
    int i1;
    if (x == 13)
      goto l1;
    i1 = 2;
    r += i1;
  }
  if (x == 3)
    goto l2;
  if (x == 4)
    goto l1;
  {
    S s3;
    if (x == 5)
      goto l2;
    S s4;
    if (x == 6)
      goto l1;
    {
      S s5;
      if (x == 7)
	goto l1;
      s5.a = 5;
      r += s5.a;
    }
    S s6;
    {
      S s7;
      S s8;
      if (x == 8)
	goto l1;
      S s9;
      if (x == 9)
	goto l2;
      if (x == 10)
	goto l2;
      if (x == 11)
	goto l2;
      l1:
      l2:
      s1.a = 1;
      s2.b = 2;
      s3.c = 3;
      s4.a = 4;
      s6.b = 6;
      s7.c = 7;
      s8.a = 8;
      s9.b = 9;
      r += s1.a + s2.b + s3.c;
      r += s4.a + s6.b + s7.c;
      r += s8.a + s9.b;
      if (x == 14)
	goto l3;
      S s11;
      switch (x)
	{
	  S s12;
	case 15:
	  S s13;
	  // FALLTHRU
	l3:
	case 16:
	case 17:
	  S s14;
	  s11.a = 1;
	  s12.b = 2;
	  s13.c = 3;
	  s14.a = 4;
	  r += s11.a + s12.b + s13.c;
	  r += s14.a;
	  return r;
	case 18:
	  S s15;
	  s11.a = 1;
	  s12.b = 2;
	  s13.c = 3;
	  s14.a = 4;
	  s15.b = 5;
	  r += s11.a + s12.b + s13.c;
	  r += s14.a + s15.b;
	  return r;
	default:
	  if (x != 19 && x != 20)
	    break;
	  S s16;
	  s11.a = 1;
	  s12.b = 2;
	  s13.c = 3;
	  s14.a = 4;
	  s15.b = 5;
	  s16.c = 6;
	  r += s11.a + s12.b + s13.c;
	  r += s14.a + s15.b + s16.c;
	  return r;
	}
      if (x == 21)
	goto l3;
    }
    S s17;
    if (x == 22)
      goto l3;
    if (x == 23)
      goto l1;
    if (x == 24)
      goto l2;
    s17.a = 1;
    r += s17.a;
  }
  S s18;
  if (x == 25)
    {
      S s19;
      s19.c = 2;
      r += s19.c;
      if (x == 29)
	l4:;
      goto l3;
    }
  if (x == 26)
    goto l1;
  if (x == 27)
    goto l2;
  s18.b = 1;
  r += s18.b;
  if (x == 28)
    goto l4;
  {
    S s20;
    {
      S s21;
      if (x == 29)
	goto l1;
      S s22;
      if (x == 30)
	goto l2;
      l5:
      s20.a = 1;
      s21.b = 2;
      s22.c = 3;
      r += s20.a + s21.b + s22.c;
      switch (x)
	{
	case 31:
	  S s23;
	  // FALLTHRU
	l6:
	case 32:
	case 33:
	  S s24;
	  s23.a = 1;
	  s24.b = 2;
	  r += s23.a + s24.b;
	  return r;
	default:
	  if (x >= 34 && x <= 35)
	    return r;
	  break;
	}
      if (x == 34)
	goto l5;
      if (x == 35)
	goto l6;
      return r;
    }
    if (x == 36)
      goto l5;
    if (x == 37)
      goto l6;
  }
  if (x == 38)
    goto l5;
  if (x == 39)
    goto l6;
  return r;
}
into a testsuite testcase with .DEFERRED_INIT call count checks for each of the vars.
Comment 7 Jakub Jelinek 2025-09-16 16:51:45 UTC
Created attachment 62390 [details]
gcc16-pr114457-wip.patch

Updated patch which handles the forward/backward gotos as well as switch jumps to case/default labels if they cross vacuous initializers for -std=c++26 or -ftrivial-auto-var-init= and handles it for -Wimplicit-fallthrough as well.
Comment 8 GCC Commits 2025-10-04 08:23:48 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:f256a13f8aed833fe964a2ba541b7b30ad9b4a76

commit r16-4212-gf256a13f8aed833fe964a2ba541b7b30ad9b4a76
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Oct 4 09:50:39 2025 +0200

    c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR114457]
    
    The following patch implements the C++26 P2795R5 paper by enabling something
    like -ftrivial-auto-var-init=zero by default for -std=c++26/-std=gnu++26.
    There is an important difference between explicit -ftrivial-auto-var-init=zero
    and the implicitly enabled one, in particular the explicit one will try to
    clear padding bits on vars with explicit initializers, while the default
    C++26 mode does not - C++26 says that using the padding bits for anything
    but copying structures around is still undefined behavior rather than
    erroneous behavior.
    
    Users can still override the default C++26 behavior in both directions,
    with -ftrivial-auto-var-init=uninitialized even C++26 will act as C++23
    with treating all uninitialized var reads (except for copying) as UB rather
    than EB, with -ftrivial-auto-var-init=zero it will also clear padding bits
    on explicit initialization and with -ftrivial-auto-var-init=pattern it will
    initialize to pattern with clearing padding bits in between.
    
    There are other changes that had to be implemented.  First of all, we need
    to magicly preinitialize also temporary objects; this is implemented for
    both the C++26 implicit mode and explicit
    -ftrivial-auto-var-init={zero,pattern} by emitting .DEFERRED_INIT before
    construction of TARGET_EXPR temporaries (if they have void type initializers,
    i.e. are initialized by code rather than some value).
    
    Second needed change is dropping *this ={v} {CLOBBER(bob)}; statements
    at the start of the constructors for -flifetime-dse=2, that says the old
    content of *this is irrelevant, which is not true anymore for C++26,
    where we want to treat it like that for -W*uninitialized purposes, but
    at runtime actually initialize the values.  Instead for -flifetime-dse=2
    we emit such {CLOBBER(bob)} before calling whole object constructor
    (on TARGET_EXPR with void type initializer or on DECL_EXPR).
    And a separate patch added and another one will be adding more {CLOBBER(bob)}
    to new expressions.
    
    The third needed change is about gotos and switches across vacuous
    initialization.  C++26 says those are still valid, but don't make an
    exception for those in the EB rules.
    The patch now includes redirecting of forward/backward gotos
    which cross vacuous initializations for -std=c++26 and
    -ftrivial-auto-var-init={zero,pattern} by adding an artificial
    if (0) { lab1: v1 = .DEFERRED_INIT (...); lab2: v2 = .DEFERRED_INIT (...); }
    etc. hunk before the user label (or for case labels moving the case
    label into it).  Only one per adjacent set of labels, with perhaps
    multiple artificial labels in it.  I believe (and testing seems to
    confirm that) that one only needs one set of such initialized vars
    per the adjacent label group, if some forward or backward jump
    crosses more vacuous inits, it will always cross a subset or superset
    of the others and when the vars are ordered right, it can jump into
    different positions in the same if (0).
    Furthermore, -Wimplicit-fallthrough and -Wswitch-unreachable warnings
    have been adjusted to deal with that.
    These changes mean that -Wtrivial-auto-var-init warning now doesn't
    make sense for C++, as there is nothing to warn about, all the switches
    and all the gotos are handled right for -ftrivial-auto-var-init= and
    are handled that way both for the implicit C++26 mode and for explicit
    -ftrivial-auto-var-init= options.
    
    The fourth change is to avoid regressions for code like
    struct A
    {
      int f, g;
      A () { f = g; // { dg-warning "g. is used uninitialized" } }
    } a;
    where with -flifetime-dse=2 -Wuninitialized we were able to warn
    about bugs like this because of the *this ={v} {CLOBBER(bob)};
    statements at the start of the constructors, but with their removal
    wouldn't warn about it.  Instead we now add a magic "clobber *this"
    attribute to the this PARM_DECL and use it in -W*uninitialized handling
    only as an implicit *this ={v} {CLOBBER(bob)}; at the start of the
    function.  If a function is inlined, this disappears, but that shouldn't
    be a problem, either it is inlined into another constructor and that
    should have "clobber *this" for its this argument or it is inlined into
    whole object construction spot and there should be an explicit
    {CLOBBER(bob)} for the variable or temporary object.
    
    The fifth change is adding [[indeterminate]] attribute support and
    using it to avoid .DEFERRED_INIT calls (like [[gnu::uninitialized]]
    is handled).
    
    Some regressions caused by this patch had bugs filed (but for cases
    where those already didn't work before with explicit
    -ftrivial-auto-var-init=zero), those have been xfailed for now.
    See PR121975 and PR122044.
    
    2025-10-04  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/114457
    gcc/
            * flag-types.h (enum auto_init_type): Add AUTO_INIT_CXX26.
            * tree.h (VACUOUS_INIT_LABEL_P): Define.
            * gimplify.cc (is_var_need_auto_init): Renamed to ...
            (var_needs_auto_init_p): ... this.  Don't return true for
            vars with "indeterminate" attribute.  Formatting fixes.
            (gimplify_decl_expr): Use var_needs_auto_init_p instead of
            is_var_need_auto_init.
            (emit_warn_switch_unreachable): Remove the flag_auto_var_init
            special cases.
            (warn_switch_unreachable_and_auto_init_r): Handle them here
            by doing just returning NULL.
            (last_stmt_in_scope): Don't skip just debug stmts to find
            the last stmt in seq, skip for
            flag_auto_var_init > AUTO_INIT_UNINITIALIZED also IFN_DEFERRED_INIT
            calls.
            (collect_fallthrough_labels): For
            flag_auto_var_init > AUTO_INIT_UNINITIALIZED ignore
            IFN_DEFERRED_INIT calls and GIMPLE_GOTOs to
            VACUOUS_INIT_LABEL_P.
            (should_warn_for_implicit_fallthrough): For
            flag_auto_var_init > AUTO_INIT_UNINITIALIZED also skip over
            IFN_DEFERRED_INIT calls.
            (expand_FALLTHROUGH_r): Likewise, and handle GIMPLE_GOTOs
            to VACUOUS_INIT_LABEL_P.
            (gimplify_init_constructor): Use var_needs_auto_init_p instead
            of is_var_need_auto_init and for flag_auto_var_init
            AUTO_INIT_CXX26 don't call gimple_add_padding_init_for_auto_var.
            (gimplify_target_expr): If var_needs_auto_init_p and init has
            void type, call gimple_add_init_for_auto_var and for
            AUTO_INIT_PATTERN also gimple_add_padding_init_for_auto_var.
            * tree-ssa-uninit.cc (maybe_warn_operand): Handle loads from *this
            at the start of the function with "clobber *this" attribute on the
            PARM_DECL.
            * ipa-split.cc (split_function): Remove "clobber *this" attribute
            from the first PARM_DECL (if any).
            * doc/invoke.texi (ftrivial-auto-var-init=): Adjust documentation.
    gcc/c-family/
            * c-opts.cc (c_common_post_options): For C++26 set
            flag_auto_var_init to AUTO_INIT_CXX26 if not specified explicitly.
            For C++ disable warn_trivial_auto_var_init.
    gcc/cp/
            * cp-tree.h: Implement C++26 P2795R5 - Erroneous behavior for
            uninitialized reads.
            (IF_STMT_VACUOUS_INIT_P): Define.
            (check_goto): Change argument type from tree to tree *.
            * call.cc (build_over_call): Add indeterminate attribute to
            TARGET_EXPR slots for indeterminate parameters.
            * constexpr.cc (cxx_eval_internal_function): Handle IFN_DEFERRED_INIT.
            (cxx_eval_store_expression): Temporarily work around PR121965 bug.
            * cp-gimplify.cc (genericize_if_stmt): Handle IF_STMT_VACUOUS_INIT_P.
            (maybe_emit_clobber_object_begin): New function.
            (cp_gimplify_expr): Call it for DECL_EXPRs and TARGET_EXPRs with
            void type non-NULL TARGET_EXPR_INITIAL.
            * decl.cc (struct named_label_fwd_direct_goto,
            struct named_label_bck_direct_goto): New types.
            (struct named_label_use_entry): Add direct_goto member.  Formatting
            fix.
            (struct named_label_entry): Add direct_goto member.  Turn bool members
            into bool : 1.  Add has_bad_decls bitfield.
            (adjust_backward_gotos): New function.
            (pop_labels): For flag_auto_var_init > AUTO_INIT_UNINITIALIZED
            call adjust_backward_gotos if needed.
            (poplevel_named_label_1): For decl_jump_unsafe also set
            ent->has_bad_decls, and for decl_instrument_init_bypass_p decls
            push them into ent->bad_decls vector too.
            (duplicate_decls): Complain if indeterminate attribute on function
            parameter isn't present on the first function declaration.
            (decl_instrument_init_bypass_p): New function.
            (build_deferred_init_call): Likewise.
            (maybe_add_deferred_init_calls): Likewise.
            (adjust_backward_goto): Likewise.
            (check_previous_goto_1): Add direct_goto and case_label arguments.
            For decl_instrument_init_bypass_p decls seen if
            direct_goto || case_label move case label if needed, call
            maybe_add_deferred_init_calls and adjust GOTO_EXPR operands remembered
            in direct_goto.  Change return type from bool to int, return 0 on
            error, 1 for success with no need to adjust vacuous inits and 2 for
            success with need to adjust those.
            (check_previous_goto): Adjust check_previous_goto_1 call, vec_free
            direct_goto vector.
            (check_switch_goto): Add case_label argument, adjust
            check_previous_goto_1 call.  Change return type from bool to int.
            (check_goto_1): Remove computed argument, add declp argument.  Don't
            reuse previous ent->uses if
            ent->binding_level != current_binding_level.  Push declp into
            direct_goto vectors if needed.
            (check_goto): Remove decl argument, add declp argument.  Adjust
            check_goto_1 calls.
            (finish_case_label): Call check_switch_goto up to twice, first time
            to detect errors and find out if second call will be needed, and
            after c_add_case_label second time if needed.  In the first case
            pass NULL_TREE as new argument to it, in the second case r.
            (start_preparsed_function): Don't emit CLOBBER_OBJECT_BEGIN here
            for -flifetime-dse=2, instead add "clobber *this" attribute to
            current_class_ptr.
            * parser.cc (cp_parser_asm_label_list): Call check_goto only
            after the TREE_LIST is created and pass address of its TREE_VALUE to
            it instead of the label.
            * semantics.cc (finish_goto_stmt): Call check_goto only after
            build_stmt has been called and pass it address of its first operand
            rather than destination.
            * tree.cc (handle_indeterminate_attribute): New function.
            (cxx_gnu_attributes): Add entry for indeterminate attribute.
    gcc/testsuite/
            * g++.dg/cpp1y/vla-initlist1.C: Remove dg-skip-if for powerpc.
            Initialize i to 43 for ctor from initializer_list and expect value
            43 instead of 42.
            * g++.dg/cpp26/attr-indeterminate1.C: New test.
            * g++.dg/cpp26/attr-indeterminate2.C: New test.
            * g++.dg/cpp26/attr-indeterminate3.C: New test.
            * g++.dg/cpp26/attr-indeterminate4.C: New test.
            * g++.dg/cpp26/erroneous1.C: New test.
            * g++.dg/cpp26/erroneous2.C: New test.
            * g++.dg/cpp26/erroneous3.C: New test.
            * g++.dg/cpp26/erroneous4.C: New test.
            * g++.dg/opt/store-merging-1.C: Add
            -ftrivial-auto-var-init=uninitialized to dg-options.
            * g++.dg/uninit-pred-loop-1_b.C: Expect a warning for C++26.
            * g++.dg/warn/Wuninitialized-13.C: Expect warning on a different
            line.
            * c-c++-common/ubsan/vla-1.c: Add
            -ftrivial-auto-var-init=uninitialized to dg-options.
            * c-c++-common/uninit-17.c: For c++26 expect warning on a different
            line.
            * g++.dg/warn/Warray-bounds-20.C: Expect warning on a different line.
            * c-c++-common/analyzer/invalid-shift-1.c: Xfail for c++26 until
            PR122044 is fixed.
            * g++.dg/analyzer/exception-value-2.C: Skip for c++26 until PR122044
            is fixed.
            * c-c++-common/goacc-gomp/nesting-1.c: Skip for c++26 until PR121975
            is fixed.
            * c-c++-common/goacc/kernels-decompose-2.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr100400-1-1.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr100400-1-3.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104061-1-1.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104061-1-3.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104061-1-4.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104132-1.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104133-1.c: Likewise.
            * c-c++-common/goacc/kernels-decompose-pr104774-1.c: Likewise.
            * c-c++-common/goacc/mdc-1.c: Likewise.
Comment 9 Jakub Jelinek 2025-10-04 09:21:40 UTC
Implemented for GCC 16.
Comment 10 Christophe Lyon 2025-10-10 12:40:22 UTC
After this patch, we now are two XPASS:
XPASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26 TODO location at line 17 (test for bogus messages, line 10)
XPASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26 TODO at line 18 (test for warnings, line 19)

they are XFAIL with -std=c++17 and -std=c++98

do we bother?
Comment 11 GCC Commits 2025-10-20 19:29:39 UTC
The trunk branch has been updated by Thomas Schwinge <tschwinge@gcc.gnu.org>:

https://gcc.gnu.org/g:6173169792d7f59c14960792a504be6d00b943eb

commit r16-4519-g6173169792d7f59c14960792a504be6d00b943eb
Author: Thomas Schwinge <tschwinge@baylibre.com>
Date:   Mon Oct 20 17:36:49 2025 +0200

    c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads: Adjust 'c-c++-common/goacc/kernels-decompose-pr100280-1.c' [PR114457]
    
    With commit r16-4212-gf256a13f8aed833fe964a2ba541b7b30ad9b4a76
    "c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR114457]",
    we acquired:
    
        @@ -181180,8 +184423,8 @@ PASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26  at line 14
        PASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26  at line 15 (test for warnings, line 12)
        PASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26  at line 16 (test for warnings, line 12)
        PASS: c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26 (test for excess errors)
        [-XFAIL:-]{+XPASS:+} c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26 TODO at line 18 (test for warnings, line 19)
        [-XFAIL:-]{+XPASS:+} c-c++-common/goacc/kernels-decompose-pr100280-1.c  -std=c++26 TODO location at line 17 (test for bogus messages, line 10)
    
    As in other OpenACC 'kernels' test cases, the underlying issue again is
    PR121975 "Various goacc failures with -ftrivial-auto-var-init=zero" (to be
    resolved later on).
    
            PR c++/114457
            gcc/testsuite/
            * c-c++-common/goacc/kernels-decompose-pr100280-1.c: Skip for
            c++26 until PR121975 is fixed.
Comment 12 GCC Commits 2025-10-20 19:29:44 UTC
The trunk branch has been updated by Thomas Schwinge <tschwinge@gcc.gnu.org>:

https://gcc.gnu.org/g:651df6b43e817a8e4b87eed9f338ea227da7bccb

commit r16-4520-g651df6b43e817a8e4b87eed9f338ea227da7bccb
Author: Thomas Schwinge <tschwinge@baylibre.com>
Date:   Mon Oct 20 17:36:49 2025 +0200

    c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads: Adjust 'libgomp.c++/{target-flex-101.C,target-std__flat_map-concurrent.C,target-std__flat_multimap-concurrent.C}' [PR114457, PR122268, PR120450]
    
    With commit r16-4212-gf256a13f8aed833fe964a2ba541b7b30ad9b4a76
    "c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR114457]",
    we acquired:
    
        {+FAIL: libgomp.c++/target-flex-101.C (internal compiler error: in assign_temp, at function.cc:990)+}
        [-PASS:-]{+FAIL:+} libgomp.c++/target-flex-101.C (test for excess errors)
        [-PASS:-]{+UNRESOLVED:+} libgomp.c++/target-flex-101.C [-execution test-]{+compilation failed to produce executable+}
    
    ... for GCN, nvptx offloading compilation, and on the other hand:
    
        [-XFAIL:-]{+XPASS:+} libgomp.c++/target-std__flat_map-concurrent.C (internal compiler error[-: in assign_temp, at function.cc:990)-]
        [-XFAIL:-]{+XPASS:+} libgomp.c++/target-std__flat_map-concurrent.C (test for excess errors)
        [-UNRESOLVED:-]{+PASS:+} libgomp.c++/target-std__flat_map-concurrent.C [-compilation failed to produce executable-]{+execution test+}
    
        [-XFAIL:-]{+XPASS:+} libgomp.c++/target-std__flat_multimap-concurrent.C (internal compiler error[-: in assign_temp, at function.cc:990)-]
        [-XFAIL:-]{+XPASS:+} libgomp.c++/target-std__flat_multimap-concurrent.C (test for excess errors)
        [-UNRESOLVED:-]{+PASS:+} libgomp.c++/target-std__flat_multimap-concurrent.C [-compilation failed to produce executable-]{+execution test+}
    
    ... for GCN offloading compilation (already PASSed for nvptx).
    
    Note that these test cases explicitly use '-std=c++23', so don't undergo the
    new C++26 P2795R5 functionality.  Yet, comparing before vs. after that commit,
    in the 'gimple' dumps (that is, early host compilation), there are a lot of
    changes where 'gimple_assign <constructor, [...], {CLOBBER(bob)}, NULL, NULL>'s
    and relatedly 'gimple_bind's newly appear/no longer appear elsewhere.  This
    leads to correspondingly different code at the beginning of offloading
    compilation.  Why/how that now ('libgomp.c++/target-flex-101.C') vs. before
    ('libgomp.c++/{target-std__flat_map-concurrent.C,target-std__flat_multimap-concurrent.C}')
    translates into 'expand' ICEs, I can't tell.
    
            PR c++/114457
            PR c++/122268
            PR c++/120450
            libgomp/
            * testsuite/libgomp.c++/target-flex-101.C: XFAIL GCN, nvptx
            offloading compilation.
            * testsuite/libgomp.c++/target-std__flat_map-concurrent.C:
            Un-XFAIL GCN offloading compilation.
            * testsuite/libgomp.c++/target-std__flat_multimap-concurrent.C:
            Likewise.