[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 Marek Polacek changed: What|Removed |Added Status|ASSIGNED|NEW CC||mpolacek at gcc dot gnu.org
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 --- Comment #7 from Thiago Macieira --- (In reply to Jakub Jelinek from comment #1) > The warning is done before optimizations (except GENERIC opts), and can > hardly be done much later. I imagined it would be the case. Treat this as low priority. I've added the [[fallthrough]] to the source code where this appeared to silence the warning. Arguably, the author should have used Q_UNREACHABLE() there too, not Q_ASSERT(!"message").
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 --- Comment #6 from Marek Polacek --- But even that is not enough for switch (i) { case 0: goto X; if (0) // nowarn X: nop (); else die (); case 1:; i++; } because we need to remember whether the then branch contained any labels.
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 --- Comment #5 from Marek Polacek --- Actually, nothing I imagined wouldn't work for the case when the else branch is dead :(. A patch that helps with bogus warning for dead then branches: --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1912,6 +1912,7 @@ collect_fallthrough_labels (gimple_stmt_iterator *gsi_p, if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND) { gcond *cond_stmt = as_a (gsi_stmt (*gsi_p)); + bool false_p = gimple_cond_false_p (cond_stmt); tree false_lab = gimple_cond_false_label (cond_stmt); location_t if_loc = gimple_location (cond_stmt); @@ -1956,7 +1957,9 @@ collect_fallthrough_labels (gimple_stmt_iterator *gsi_p, = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH); gsi_next (gsi_p); tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p)); - if (!fallthru_before_dest) + /* If FALSE_P, the then branch is dead, do not collect +the label. */ + if (!fallthru_before_dest && !false_p) { struct label_entry l = { goto_dest, if_loc }; labels->safe_push (l);
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 Marek Polacek changed: What|Removed |Added Status|UNCONFIRMED |ASSIGNED Last reconfirmed||2017-04-19 Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #4 from Marek Polacek --- I think it shouldn't affect those at all. Another idea is to return fake FALLTHROUGH () if the else branch is dead. Let me see. extern void die (void) __attribute__((noreturn)); extern void nop (void); void f (int i) { switch (i) { case 0: if (1) die (); else nop (); case 1:; i++; } switch (i) { case 0: if (0) die (); else nop (); case 1:; i++; } switch (i) { case 0: if (1) nop (); else die (); case 1:; i++; } switch (i) { case 0: if (0) nop (); else die (); case 1:; i++; } }
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 --- Comment #3 from Jakub Jelinek --- Would that disable warning for: if (0) switch (x) { case 5: x++; case 6: x += 17; break; } ? Perhaps that is ok. Wouldn't that also disable warning for: if (x > 24) goto lab; if (0) { lab: switch (x) { case 37: x++; case 38: x += 18; break; } } ? On the latter we should warn...
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 --- Comment #2 from Marek Polacek --- I thought we could (in collect_fallthrough_labels) look at the GIMPLE_COND, see if its OP0 and OP1 are INTEGER_CSTs, and if they are, determine which branch cannot be taken, and then maybe don't do labels->safe_push (l); which should suppress the warning.
[Bug c++/80460] Incorrect fallthrough warning after [[noreturn]] function inside always-true conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80460 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org, ||mpolacek at gcc dot gnu.org --- Comment #1 from Jakub Jelinek --- The warning is done before optimizations (except GENERIC opts), and can hardly be done much later. In *.original we have: case 0:; <; case 1:; <; and what the warning code sees in *.gimple when it is performed is: switch (i) , case 0: , case 1: > : if (1 != 0) goto ; else goto ; : qt_assert (); : qt_noop (); : qt_noop (); : So, to get rid of the warning, we'd need to do some optimization already during the gimplification, perhaps if we have COND_EXPR with constant condition scan the non-active branch and if there are no labels in there, don't try to gimplify it at all? Walking it for all COND_EXPRs with constant condition would have undesirable compile time complexity though if there are any labels. And trying to prove if some code is reachable or not reachable at gimplification time is not really doable, we don't have CFG. Moving the warning later is also undesirable, because the IL would be mangled and wouldn't match the original source the way we need.