re PR c++/67409 (tree-cfg.c dereferences a NULL pointer)
authorJakub Jelinek <jakub@redhat.com>
Thu, 19 Nov 2015 16:18:39 +0000 (17:18 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 19 Nov 2015 16:18:39 +0000 (17:18 +0100)
PR c++/67409
* decl.c (identify_goto): Add LOC and DIAG_KIND arguments, call
emit_diagnostic instead of permerror.
(check_previous_goto_1): Adjust identify_goto callers, treat all
cases but crossing initialization and entering scope of decl with
non-trivial dtor as unconditional hard errors.
(check_goto): Use identify_goto.  Treat all cases but crossing
initialization and entering scope of decl with non-trivial dtor
as unconditional hard errors.

* g++.dg/eh/goto3.C: New test.

Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r230613

gcc/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/goto3.C [new file with mode: 0644]

index de3318c55409d374f0930fc62f8a968b72a6bce5..1013d8fbd7929182777f9ee1860ee5fe04bff06f 100644 (file)
@@ -1,3 +1,16 @@
+2015-11-19  Jakub Jelinek  <jakub@redhat.com>
+           Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c++/67409
+       * decl.c (identify_goto): Add LOC and DIAG_KIND arguments, call
+       emit_diagnostic instead of permerror.
+       (check_previous_goto_1): Adjust identify_goto callers, treat all
+       cases but crossing initialization and entering scope of decl with
+       non-trivial dtor as unconditional hard errors.
+       (check_goto): Use identify_goto.  Treat all cases but crossing
+       initialization and entering scope of decl with non-trivial dtor
+       as unconditional hard errors.
+
 2015-11-19  Michael Matz  <matz@suse.de>
 
        * fwprop.c (update_uses): Use flag_checking instead of
index 675342efcd9f0ac31df18d9e6f51d484ba2ed785..e895c5a06ce8d756c6b0d2594a3606bb8e3cc9d9 100644 (file)
@@ -2967,14 +2967,16 @@ decl_jump_unsafe (tree decl)
   return 0;
 }
 
-/* A subroutine of check_previous_goto_1 to identify a branch to the user.  */
+/* A subroutine of check_previous_goto_1 and check_goto to identify a branch
+   to the user.  */
 
 static bool
-identify_goto (tree decl, const location_t *locus)
+identify_goto (tree decl, location_t loc, const location_t *locus,
+              diagnostic_t diag_kind)
 {
-  bool complained = (decl
-                    ? permerror (input_location, "jump to label %qD", decl)
-                    : permerror (input_location, "jump to case label"));
+  bool complained
+    = (decl ? emit_diagnostic (diag_kind, loc, 0, "jump to label %qD", decl)
+           : emit_diagnostic (diag_kind, loc, 0, "jump to case label"));
   if (complained && locus)
     inform (*locus, "  from here");
   return complained;
@@ -2991,15 +2993,17 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
                       bool exited_omp, const location_t *locus)
 {
   cp_binding_level *b;
-  bool identified = false, complained = false;
+  bool complained = false;
+  int identified = 0;
   bool saw_eh = false, saw_omp = false, saw_tm = false;
 
   if (exited_omp)
     {
-      complained = identify_goto (decl, locus);
+      complained = identify_goto (decl, input_location, locus, DK_ERROR);
       if (complained)
        inform (input_location, "  exits OpenMP structured block");
-      identified = saw_omp = true;
+      saw_omp = true;
+      identified = 2;
     }
 
   for (b = current_binding_level; b ; b = b->level_chain)
@@ -3016,8 +3020,9 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
 
          if (!identified)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_PERMERROR);
+             identified = 1;
            }
          if (complained)
            {
@@ -3035,10 +3040,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
        break;
       if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
        {
-         if (!identified)
+         if (identified < 2)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
            }
          if (complained)
            {
@@ -3051,10 +3057,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
        }
       if (b->kind == sk_omp && !saw_omp)
        {
-         if (!identified)
+         if (identified < 2)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
            }
          if (complained)
            inform (input_location, "  enters OpenMP structured block");
@@ -3062,10 +3069,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
        }
       if (b->kind == sk_transaction && !saw_tm)
        {
-         if (!identified)
+         if (identified < 2)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
            }
          if (complained)
            inform (input_location,
@@ -3098,7 +3106,8 @@ void
 check_goto (tree decl)
 {
   struct named_label_entry *ent, dummy;
-  bool saw_catch = false, identified = false, complained = false;
+  bool saw_catch = false, complained = false;
+  int identified = 0;
   tree bad;
   unsigned ix;
 
@@ -3141,11 +3150,13 @@ check_goto (tree decl)
   if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope
       || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
     {
-      complained = permerror (DECL_SOURCE_LOCATION (decl),
-                             "jump to label %qD", decl);
-      if (complained)
-       inform (input_location, "  from here");
-      identified = true;
+      diagnostic_t diag_kind = DK_PERMERROR;
+      if (ent->in_try_scope || ent->in_catch_scope
+         || ent->in_transaction_scope || ent->in_omp_scope)
+       diag_kind = DK_ERROR;
+      complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+                                 &input_location, diag_kind);
+      identified = 1 + (diag_kind == DK_ERROR);
     }
 
   FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
@@ -3155,6 +3166,12 @@ check_goto (tree decl)
       if (u > 1 && DECL_ARTIFICIAL (bad))
        {
          /* Can't skip init of __exception_info.  */
+         if (identified == 1)
+           {
+             complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+                                         &input_location, DK_ERROR);
+             identified = 2;
+           }
          if (complained)
            inform (DECL_SOURCE_LOCATION (bad), "  enters catch block");
          saw_catch = true;
@@ -3195,13 +3212,12 @@ check_goto (tree decl)
            break;
          if (b->kind == sk_omp)
            {
-             if (!identified)
+             if (identified < 2)
                {
-                 complained = permerror (DECL_SOURCE_LOCATION (decl),
-                                         "jump to label %qD", decl);
-                 if (complained)
-                   inform (input_location, "  from here");
-                 identified = true;
+                 complained = identify_goto (decl,
+                                             DECL_SOURCE_LOCATION (decl),
+                                             &input_location, DK_ERROR);
+                 identified = 2;
                }
              if (complained)
                inform (input_location, "  exits OpenMP structured block");
index 7b6565914e446c9fbb64d7810f811e8576ed1fa8..2d4962d74897d440f8fba05c7e37acf07147da4e 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/67409
+       * g++.dg/eh/goto3.C: New test.
+
 2015-11-19  Marek Polacek  <polacek@redhat.com>
 
        PR tree-optimization/68431
diff --git a/gcc/testsuite/g++.dg/eh/goto3.C b/gcc/testsuite/g++.dg/eh/goto3.C
new file mode 100644 (file)
index 0000000..d584ad7
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/67409
+// { dg-options "-fpermissive" }
+
+void f()
+try
+  {
+    goto l2;       // { dg-message "from here" }
+  l1: ;            // { dg-error "jump to label 'l1'" }
+  } catch (...)
+  {
+  l2: ;            // { dg-error "jump to label 'l2'" }
+                  // { dg-message "enters catch block" "" { target *-*-*} 11 }
+    goto l1;       // { dg-message "from here|enters try block" }
+  }