https://gcc.gnu.org/g:d9318caed3bbff8136d13e00dcfc020a59d10f78

commit r15-329-gd9318caed3bbff8136d13e00dcfc020a59d10f78
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed Jan 24 18:06:48 2024 -0500

    c++: #pragma doesn't disable -Wunused-label [PR113582]
    
    The PR complains that
    
      void do_something(){
        #pragma GCC diagnostic push
        #pragma GCC diagnostic ignored "-Wunused-label"
        start:;
        #pragma GCC diagnostic pop
      } #1
    
    doesn't work.  That's because we warn_for_unused_label only while we're
    in finish_function, meaning we're at #1 where we're outside the #pragma
    region.  We can use suppress_warning + warning_suppressed_p to fix this.
    
    Note that I'm not using TREE_USED.  Propagating it in tsubst_stmt/LABEL_EXPR
    from decl to label would mean that we don't warn in do_something2, but
    I think we want the warning there: we're in a template and the goto is
    a discarded statement.
    
            PR c++/113582
    
    gcc/c-family/ChangeLog:
    
            * c-warn.cc (warn_for_unused_label): Don't warn if -Wunused-label 
has
            been suppressed for the label.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_label_for_labeled_statement): 
suppress_warning
            if it's not enabled at input_location.
            * pt.cc (tsubst_stmt): Call copy_warning.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/warn/Wunused-label-4.C: New test.

Diff:
---
 gcc/c-family/c-warn.cc                      |  4 +++-
 gcc/cp/parser.cc                            |  6 +++++-
 gcc/cp/pt.cc                                |  9 +++++----
 gcc/testsuite/g++.dg/warn/Wunused-label-4.C | 29 +++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index bff87be05ae3..5b2d6805c790 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -2185,7 +2185,9 @@ warn_for_unused_label (tree label)
 {
   if (!TREE_USED (label))
     {
-      if (DECL_INITIAL (label))
+      if (warning_suppressed_p (label, OPT_Wunused_label))
+       /* Don't warn.  */;
+      else if (DECL_INITIAL (label))
        warning (OPT_Wunused_label, "label %q+D defined but not used", label);
       else
        warning (OPT_Wunused_label, "label %q+D declared but not defined", 
label);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index c4191200291d..7306ce9a8a8b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -13108,7 +13108,11 @@ cp_parser_label_for_labeled_statement (cp_parser* 
parser, tree attributes)
       /* Anything else must be an ordinary label.  */
       label = finish_label_stmt (cp_parser_identifier (parser));
       if (label && TREE_CODE (label) == LABEL_DECL)
-       FALLTHROUGH_LABEL_P (label) = fallthrough_p;
+       {
+         FALLTHROUGH_LABEL_P (label) = fallthrough_p;
+         if (!warning_enabled_at (input_location, OPT_Wunused_label))
+           suppress_warning (label, OPT_Wunused_label);
+       }
       break;
     }
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1816bfd1f401..8787eabb9fdb 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -18837,11 +18837,12 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
     case LABEL_EXPR:
       {
        tree decl = LABEL_EXPR_LABEL (t);
-       tree label;
-
-       label = finish_label_stmt (DECL_NAME (decl));
+       tree label = finish_label_stmt (DECL_NAME (decl));
        if (TREE_CODE (label) == LABEL_DECL)
-         FALLTHROUGH_LABEL_P (label) = FALLTHROUGH_LABEL_P (decl);
+         {
+           FALLTHROUGH_LABEL_P (label) = FALLTHROUGH_LABEL_P (decl);
+           copy_warning (label, decl);
+         }
        if (DECL_ATTRIBUTES (decl) != NULL_TREE)
          cplus_decl_attributes (&label, DECL_ATTRIBUTES (decl), 0);
       }
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-label-4.C 
b/gcc/testsuite/g++.dg/warn/Wunused-label-4.C
new file mode 100644
index 000000000000..d194f043d215
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-label-4.C
@@ -0,0 +1,29 @@
+// PR c++/113582
+// { dg-do compile { target c++17 } }
+// { dg-options "-Wunused-label" }
+
+template<bool B> void
+do_something ()
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-label"
+start:
+  if constexpr(B)
+    goto start;
+#pragma GCC diagnostic pop
+}
+
+template<bool B> void
+do_something2 ()
+{
+start: // { dg-warning "defined but not used" }
+  if constexpr(B)
+    goto start;
+}
+
+void
+g ()
+{
+  do_something<0>();
+  do_something2<0>();
+}

Reply via email to