aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-08-01 18:49:39 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2024-08-01 18:49:39 +0200
commit295b729da5aa430a8c5df1422644159ca8bf8dcb (patch)
treeb44ffba47669a9a39b7eec5671391b4afe4cb06d
parent1f53319cae81aea438b6c0ba55f49e5669acf1c8 (diff)
downloadgcc-295b729da5aa430a8c5df1422644159ca8bf8dcb.zip
gcc-295b729da5aa430a8c5df1422644159ca8bf8dcb.tar.gz
gcc-295b729da5aa430a8c5df1422644159ca8bf8dcb.tar.bz2
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 <jakub@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.
-rw-r--r--gcc/cp/semantics.cc2
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp11.C19
2 files changed, 21 insertions, 0 deletions
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a9abf32..669da4a 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 0000000..985f40f
--- /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;
+ }
+}