re PR c++/77886 (-Wimplicit-fallthrough: breaks duff's device (in function templates))

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.

From-SVN: r241700
This commit is contained in:
Jakub Jelinek 2016-10-31 14:39:49 +01:00 committed by Jakub Jelinek
parent 84ff4775d4
commit e8d8d3c8bf
4 changed files with 84 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2016-10-31 Jakub Jelinek <jakub@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.
2016-09-11 Le-Chun Wu <lcwu@google.com>
Mark Wielaard <mjw@redhat.com>

View File

@ -1,3 +1,8 @@
2016-10-31 Jakub Jelinek <jakub@redhat.com>
PR c++/77886
* g++.dg/warn/Wimplicit-fallthrough-2.C: New test.
2016-09-11 Le-Chun Wu <lcwu@google.com>
Mark Wielaard <mjw@redhat.com>

View File

@ -15487,7 +15487,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
{
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;
@ -15497,6 +15500,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
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);
}

View File

@ -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);
}