On 7/29/24 3:42 AM, Jakub Jelinek wrote:
Hi!
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).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
2024-07-29 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.
--- gcc/cp/semantics.cc.jj 2024-07-24 15:47:15.238477295 +0200
+++ gcc/cp/semantics.cc 2024-07-27 09:44:44.537658588 +0200
@@ -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 swit
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);
--- gcc/testsuite/g++.dg/cpp26/decomp11.C.jj 2024-07-27 09:49:54.931612663
+0200
+++ gcc/testsuite/g++.dg/cpp26/decomp11.C 2024-07-27 09:52:09.411859739
+0200
@@ -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;
+ }
+}
Jakub