[C++ PATCH] Fix -Wimplicit-fallthrough in templates (PR c++/77886)

Jakub Jelinek jakub@redhat.com
Sat Oct 8 06:15:00 GMT 2016


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  <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.

	* 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



More information about the Gcc-patches mailing list