diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-08-01 18:49:39 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-08-01 18:49:39 +0200 |
commit | 295b729da5aa430a8c5df1422644159ca8bf8dcb (patch) | |
tree | b44ffba47669a9a39b7eec5671391b4afe4cb06d | |
parent | 1f53319cae81aea438b6c0ba55f49e5669acf1c8 (diff) | |
download | gcc-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.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp26/decomp11.C | 19 |
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; + } +} |