Hi! As the testcase shows, we weren't copying over FALLTHROUGH_LABEL_P during instantiations, which means that // FALLTHROUGH comments in templates were ignored (while [[fallthrough]];, being represented as internal calls, worked fine).
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-10-08 Jakub Jelinek <ja...@redhat.com> PR c++/77886 * pt.c (tsubst_expr) <case CASE_LABEL_EXPR> Copy over FALLTHROUGH_LABEL_P flag to the new LABEL_DECL. (tsubst_expr) <case LABEL_EXPR>: Likewise. * g++.dg/warn/Wimplicit-fallthrough-2.C: New test. --- gcc/cp/pt.c.jj 2016-10-07 21:36:47.000000000 +0200 +++ gcc/cp/pt.c 2016-10-07 23:51:53.244510627 +0200 @@ -15456,7 +15456,10 @@ tsubst_expr (tree t, tree args, tsubst_f { tree low = RECUR (CASE_LOW (t)); tree high = RECUR (CASE_HIGH (t)); - finish_case_label (EXPR_LOCATION (t), low, high); + tree l = finish_case_label (EXPR_LOCATION (t), low, high); + if (l && TREE_CODE (l) == CASE_LABEL_EXPR) + FALLTHROUGH_LABEL_P (CASE_LABEL (l)) + = FALLTHROUGH_LABEL_P (CASE_LABEL (t)); } break; @@ -15466,6 +15469,8 @@ tsubst_expr (tree t, tree args, tsubst_f tree label; label = finish_label_stmt (DECL_NAME (decl)); + if (TREE_CODE (label) == LABEL_DECL) + FALLTHROUGH_LABEL_P (label) = FALLTHROUGH_LABEL_P (decl); if (DECL_ATTRIBUTES (decl) != NULL_TREE) cplus_decl_attributes (&label, DECL_ATTRIBUTES (decl), 0); } --- gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-2.C.jj 2016-10-07 23:59:03.851102742 +0200 +++ gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-2.C 2016-10-08 00:04:25.759058055 +0200 @@ -0,0 +1,66 @@ +// PR c++/77886 +// { dg-do compile } +// { dg-options "-Wimplicit-fallthrough" } + +template <int N> +int +foo (int x, int y) +{ + switch (x) + { + case 1: + x++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + // FALLTHROUGH + case 2: + x++; + break; + case 3: + x++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + // FALLTHROUGH + lab: + case 4: + x++; + break; + case 5: + x++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + // FALLTHROUGH + default: + x++; + break; + case 26: + goto lab; + } +#if __cplusplus >= 201103L + switch (y) + { + case 1: + y++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + [[fallthrough]]; + case 2: + y++; + break; + case 3: + y++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + [[fallthrough]]; + lab2: + case 4: + y++; + break; + case 5: + y++; // { dg-bogus "this statement may f\[ahlotu\]*gh" } + [[fallthrough]]; + default: + y++; + break; + case 26: + goto lab2; + } +#endif + return x + y; +} + +int +bar (int x, int y) +{ + return foo<0> (x, y); +} Jakub