https://gcc.gnu.org/g:295b729da5aa430a8c5df1422644159ca8bf8dcb

commit r15-2645-g295b729da5aa430a8c5df1422644159ca8bf8dcb
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Aug 1 18:49:39 2024 +0200

    c++: Fix up error recovery of invalid structured bindings used in 
conditions [PR116113]
    
    The following testcase ICEs, because for structured binding error recovery
    DECL_DECOMP_BASE is kept NULL and the newly added code to pick up saved
    value from the base assumes that on structured binding bases the
    TARGET_EXPR will be always there (that is the case if there are no errors).
    
    The following patch fixes it by testing DECL_DECOMP_BASE before
    dereferencing it, another option would be not to do that if
    error_operand_p (cond).
    
    2024-08-01  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/116113
            * semantics.cc (maybe_convert_cond): Check DECL_DECOMP_BASE
            is non-NULL before dereferencing it.
            (finish_switch_cond): Likewise.
    
            * g++.dg/cpp26/decomp11.C: New test.

Diff:
---
 gcc/cp/semantics.cc                   |  2 ++
 gcc/testsuite/g++.dg/cpp26/decomp11.C | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a9abf32e01ff..669da4ad9698 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -972,6 +972,7 @@ maybe_convert_cond (tree cond)
      result in a TARGET_EXPR, pick it up from there.  */
   if (DECL_DECOMPOSITION_P (cond)
       && DECL_DECOMP_IS_BASE (cond)
+      && DECL_DECOMP_BASE (cond)
       && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
     cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
 
@@ -1714,6 +1715,7 @@ finish_switch_cond (tree cond, tree switch_stmt)
         conversion result in a TARGET_EXPR, pick it up from there.  */
       if (DECL_DECOMPOSITION_P (cond)
          && DECL_DECOMP_IS_BASE (cond)
+         && DECL_DECOMP_BASE (cond)
          && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
        cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
       cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp11.C 
b/gcc/testsuite/g++.dg/cpp26/decomp11.C
new file mode 100644
index 000000000000..985f40f2f335
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp11.C
@@ -0,0 +1,19 @@
+// PR c++/116113
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+extern int b[];
+
+void
+foo ()
+{
+  auto [a] = b;        // { dg-error "is incomplete" }
+               // { dg-warning "structured bindings only available with" "" { 
target c++14_down } .-1 }
+  if (a)
+    ;
+  switch (a)
+    {
+    default:
+      break;
+    }
+}

Reply via email to