re PR c++/77886 (-Wimplicit-fallthrough: breaks duff's device (in function templates))
authorJakub Jelinek <jakub@redhat.com>
Mon, 31 Oct 2016 13:39:49 +0000 (14:39 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 31 Oct 2016 13:39:49 +0000 (14:39 +0100)
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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-2.C [new file with mode: 0644]

index 7905d955cfe352af032fada315650220cab615b4..9a45b66d84601c840eb2b9962144e0c9f08243e4 100644 (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>
 
index be439ec3a386aaec3920f404062bf972f7f2c748..39da99ee1a993caf1cb4f25d66bb366853205ddb 100644 (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>
 
index c916e58482fa09941ecf46a97cc0850c7728a8d2..73522131b6343664c9b065c46f53369ec43f1bde 100644 (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);
       }
diff --git a/gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-2.C b/gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-2.C
new file mode 100644 (file)
index 0000000..cacaf55
--- /dev/null
@@ -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);
+}