]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: debug location of variable cleanups [PR88742]
authorJason Merrill <jason@redhat.com>
Tue, 13 Apr 2021 20:18:54 +0000 (16:18 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 14 Apr 2021 00:17:58 +0000 (20:17 -0400)
PR49951 complained about the debugger jumping back to the declaration of a
local variable when we run its destructor.  That was fixed in 4.7, but broke
again in 4.8.  PR58123 fixed an inconsistency in the behavior, but not the
jumping around.  This patch addresses the issue by setting EXPR_LOCATION on
a cleanup destructor call to the location of the closing brace of the
compound-statement, or whatever token ends the scope of the variable.

The change to cp_parser_compound_statement is so input_location is the }
rather than the ; of the last substatement.

gcc/cp/ChangeLog:

PR c++/88742
PR c++/49951
PR c++/58123
* semantics.c (set_cleanup_locs): New.
(do_poplevel): Call it.
* parser.c (cp_parser_compound_statement): Consume the }
before finish_compound_stmt.

gcc/testsuite/ChangeLog:

PR c++/88742
* g++.dg/debug/cleanup1.C: New test.
* c-c++-common/Wimplicit-fallthrough-6.c: Adjust diagnostic line.
* c-c++-common/Wimplicit-fallthrough-7.c: Likewise.
* g++.dg/cpp2a/constexpr-dtor3.C: Likewise.
* g++.dg/ext/constexpr-attr-cleanup1.C: Likewise.
* g++.dg/tm/inherit2.C: Likewise.
* g++.dg/tm/unsafe1.C: Likewise.
* g++.dg/warn/Wimplicit-fallthrough-1.C: Likewise.
* g++.dg/gcov/gcov-2.C: Adjust coverage counts.

gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/c-c++-common/Wimplicit-fallthrough-6.c
gcc/testsuite/c-c++-common/Wimplicit-fallthrough-7.c
gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C
gcc/testsuite/g++.dg/debug/cleanup1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/constexpr-attr-cleanup1.C
gcc/testsuite/g++.dg/gcov/gcov-2.C
gcc/testsuite/g++.dg/tm/inherit2.C
gcc/testsuite/g++.dg/tm/unsafe1.C
gcc/testsuite/g++.dg/warn/Wimplicit-fallthrough-1.C

index 8b7801b2be73215bfba59e8608507bbcff5748aa..aec3aa3587ff09926a259962288d7fa7fb063ab4 100644 (file)
@@ -12126,11 +12126,12 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   if (function_body)
     maybe_splice_retval_cleanup (compound_stmt);
 
-  /* Finish the compound-statement.  */
-  finish_compound_stmt (compound_stmt);
   /* Consume the `}'.  */
   braces.require_close (parser);
 
+  /* Finish the compound-statement.  */
+  finish_compound_stmt (compound_stmt);
+
   return compound_stmt;
 }
 
index 8eaaaefe2d6116d156fcdf224ad31701cedfe5db..125772238d3cb7681262c8b096d21e8e5c1479e3 100644 (file)
@@ -602,6 +602,22 @@ add_decl_expr (tree decl)
   add_stmt (r);
 }
 
+/* Set EXPR_LOCATION of the cleanups of any CLEANUP_STMT in STMTS to LOC.  */
+
+static void
+set_cleanup_locs (tree stmts, location_t loc)
+{
+  if (TREE_CODE (stmts) == CLEANUP_STMT)
+    {
+      protected_set_expr_location (CLEANUP_EXPR (stmts), loc);
+      set_cleanup_locs (CLEANUP_BODY (stmts), loc);
+    }
+  else if (TREE_CODE (stmts) == STATEMENT_LIST)
+    for (tree_stmt_iterator i = tsi_start (stmts);
+        !tsi_end_p (i); tsi_next (&i))
+      set_cleanup_locs (tsi_stmt (i), loc);
+}
+
 /* Finish a scope.  */
 
 tree
@@ -614,6 +630,9 @@ do_poplevel (tree stmt_list)
 
   stmt_list = pop_stmt_list (stmt_list);
 
+  /* input_location is the last token of the scope, usually a }.  */
+  set_cleanup_locs (stmt_list, input_location);
+
   if (!processing_template_decl)
     {
       stmt_list = c_build_bind_expr (input_location, block, stmt_list);
index 32d5febda830b8c06130568e04f2a6ebe925c76b..9593f670709efa4e878ce77a453a1cd880f06327 100644 (file)
@@ -121,8 +121,8 @@ L1:
        int j = 0;
        bar (j);
        if (j == 8)
-         return; /* { dg-warning "statement may fall through" "" { target c++ } } */
-      }
+         return;
+      } /* { dg-warning "statement may fall through" "" { target c++ } } */
     case 2:
       bar (99);
     }
@@ -151,8 +151,8 @@ L1:
        if (j == 8)
          bar (1);
        else
-         return; /* { dg-warning "statement may fall through" "" { target c++ } } */
-      }
+         return;
+      } /* { dg-warning "statement may fall through" "" { target c++ } } */
     case 2:
       bar (99);
     }
@@ -181,8 +181,8 @@ L1:
        if (j == 8)
          bar (1);
        else
-         bar (2); /* { dg-warning "statement may fall through" "" { target c++ } } */
-      }
+         bar (2);
+      } /* { dg-warning "statement may fall through" "" { target c++ } } */
     case 2:
       bar (99);
     }
@@ -281,8 +281,8 @@ L1:
     case 1:
       { /* { dg-warning "statement may fall through" "" { target c } } */
        int j = 9;
-       switch (j); /* { dg-warning "statement may fall through" "" { target c++ } } */
-      }
+       switch (j);
+      } /* { dg-warning "statement may fall through" "" { target c++ } } */
     case 2:
       bar (99);
     }
index a602216fa730f977edcfd9ef36000a9812d614ba..343b625080727486c38dd84566b50b811b2611a0 100644 (file)
@@ -22,8 +22,8 @@ f (int i)
     {
     case 1:
       { /* { dg-warning "statement may fall through" "" { target c } } */
-       int a[i]; /* { dg-warning "statement may fall through" "" { target c++ } } */
-      }
+       int a[i];
+      } /* { dg-warning "statement may fall through" "" { target c++ } } */
     case 2:
       bar (99);
     }
index 193ae93933dea2d98b5b8c34c1c87d6019607041..7700bb7b03658a908365d2aa25bb4cd7d3848f34 100644 (file)
@@ -149,9 +149,9 @@ constexpr int x3 = f3 ();
 constexpr int
 f4 ()
 {
-  W7 w13 = 5;                  // { dg-message "in 'constexpr' expansion of" }
+  W7 w13 = 5;
   return 0;
-}
+}                      // { dg-message "in 'constexpr' expansion of" }
 
 constexpr int x4 = f4 ();      // { dg-message "in 'constexpr' expansion of" }
 
diff --git a/gcc/testsuite/g++.dg/debug/cleanup1.C b/gcc/testsuite/g++.dg/debug/cleanup1.C
new file mode 100644 (file)
index 0000000..ae0515a
--- /dev/null
@@ -0,0 +1,41 @@
+// PR c++/88742
+// { dg-additional-options -fdump-tree-gimple-lineno }
+
+
+class C {
+public:
+  C() {}
+  ~C() {}
+  operator int() { return 1; }
+};
+
+int main() {
+  C a;
+  C b;
+  C c;
+
+  if (C e = C())
+    {
+      if (C d = C())
+        {
+        }
+      else
+        {
+          return 42;
+        } // { dg-final { scan-tree-dump-times ":25:9. C::~C" 1 "gimple" } }
+    } // { dg-final { scan-tree-dump-times ":26:5. C::~C" 1 "gimple" } }
+
+  while (C f = C())
+    {
+      break;
+    } // { dg-final { scan-tree-dump-times ":31:5. C::~C" 1 "gimple" } }
+
+  for (C h = C(); C i = C(); )
+    break; // { dg-final { scan-tree-dump-times ":34:10. C::~C" 2 "gimple" } }
+
+  switch (C g = C())
+    {
+    default:
+      break;
+    } // { dg-final { scan-tree-dump-times ":40:5. C::~C" 1 "gimple" } }
+} // { dg-final { scan-tree-dump-times ":41:1. C::~C" 3 "gimple" } }
index b6e7c6913673bd65a7dc03c50b4c87b42bc82d94..ab5fd17e815adbe045bc9c7ce1c745f895221a29 100644 (file)
@@ -15,9 +15,9 @@ cleanup2 (int *x)
 constexpr bool
 foo ()
 {
-  int a __attribute__((cleanup (cleanup))) = 1;        // { dg-message "in 'constexpr' expansion of" }
+  int a __attribute__((cleanup (cleanup))) = 1;
   return true;
-}
+} // { dg-message "in 'constexpr' expansion of" }
 
 constexpr bool
 bar ()
index 6d002f5d2cd01d7818d14c45ae7092924d2fa8d8..2b4cdd844e95c7871ca02c9e2c3d4eb24c5ae41a 100644 (file)
@@ -20,9 +20,9 @@ private:
 
 void foo()
 {
-  C c;                                 /* count(2) */
+  C c;                                 /* count(1) */
   c.seti (1);                          /* count(1) */
-}
+}                                      /* count(1) */
 
 int main()
 {
index 3b696a9ffb686e41090a1dc7178cebd5a0c4c1c8..366f9b30e90927cacbfe3be4e4a0914d7ab05500 100644 (file)
@@ -26,8 +26,8 @@ int main()
     B b; // ok
     D1 d1; // ok
     B& b1 = d1;
-    D2 x; // { dg-error "" "destructor of D2 is not transaction-safe" }
+    D2 x;
     b1.f(); // ok, calls D1::f()
     delete b2; // undefined behavior: calls unsafe destructor of D2
-  }
+  } // { dg-error "" "destructor of D2 is not transaction-safe" }
 }
index 49dd564894a59894d0aa302677551af23d2d2e3a..710fb1a303135d9283291adb257955359be32d53 100644 (file)
@@ -5,8 +5,8 @@ struct S {
   virtual ~S();
 };
 void f() transaction_safe {
-  S s;              // { dg-error "unsafe" "invocation of unsafe destructor" }
-}
+  S s;
+} // { dg-error "unsafe" "invocation of unsafe destructor" }
 
 int g(int x) { // is transaction-safe
   if (x <= 0)
index 053ed6885c597bed0e6cbb1a71225659ec254689..b5ebd3daaad914f9b18738dc1d5f5a5f4e44ab5f 100644 (file)
@@ -25,8 +25,8 @@ fn2 ()
   switch (0) {
   case 0:
   {
-    A b; // { dg-warning "statement may fall through" }
-  }
+    A b;
+  } // { dg-warning "statement may fall through" }
   default:
     a = 0;
   }