]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Conditionally start timer during lazy load [PR115165]
authorNathaniel Shead <nathanieloshead@gmail.com>
Sun, 7 Jul 2024 13:19:52 +0000 (23:19 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Thu, 18 Jul 2024 03:07:32 +0000 (13:07 +1000)
While lazy loading, instantiation of pendings can sometimes recursively
perform name lookup and begin further lazy loading.  When using the
'-ftime-report' functionality this causes ICEs as we could start an
already-running timer for the importing.

This patch fixes the issue by using the 'timevar_cond*' API instead to
support such recursive calls.

PR c++/115165

gcc/cp/ChangeLog:

* module.cc (lazy_load_binding): Use 'timevar_cond*' APIs.
(lazy_load_pendings): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/modules/timevar-1_a.H: New test.
* g++.dg/modules/timevar-1_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/timevar-1_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/timevar-1_b.C [new file with mode: 0644]

index d385b422168f4298da98ff8bd83e0ac5db2313d5..69764fd772d3756fac081de7527cb1e6e54d9982 100644 (file)
@@ -19604,7 +19604,7 @@ lazy_load_binding (unsigned mod, tree ns, tree id, binding_slot *mslot)
 {
   int count = errorcount + warningcount;
 
-  timevar_start (TV_MODULE_IMPORT);
+  bool timer_running = timevar_cond_start (TV_MODULE_IMPORT);
 
   /* Make sure lazy loading from a template context behaves as if
      from a non-template context.  */
@@ -19634,7 +19634,7 @@ lazy_load_binding (unsigned mod, tree ns, tree id, binding_slot *mslot)
 
   function_depth--;
 
-  timevar_stop (TV_MODULE_IMPORT);
+  timevar_cond_stop (TV_MODULE_IMPORT, timer_running);
 
   if (!ok)
     fatal_error (input_location,
@@ -19673,7 +19673,7 @@ lazy_load_pendings (tree decl)
 
   int count = errorcount + warningcount;
 
-  timevar_start (TV_MODULE_IMPORT);
+  bool timer_running = timevar_cond_start (TV_MODULE_IMPORT);
   bool ok = !recursive_lazy ();
   if (ok)
     {
@@ -19707,7 +19707,7 @@ lazy_load_pendings (tree decl)
       function_depth--;
     }
 
-  timevar_stop (TV_MODULE_IMPORT);
+  timevar_cond_stop (TV_MODULE_IMPORT, timer_running);
 
   if (!ok)
     fatal_error (input_location, "failed to load pendings for %<%E%s%E%>",
diff --git a/gcc/testsuite/g++.dg/modules/timevar-1_a.H b/gcc/testsuite/g++.dg/modules/timevar-1_a.H
new file mode 100644 (file)
index 0000000..efd7f0e
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/115165
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename> struct A { virtual ~A(); };
+struct B : A<char> {};
+struct C : B { C() {} };
+
+class D { C c; };
+void f(D);
+
+struct X {
+  friend void f(X);
+};
diff --git a/gcc/testsuite/g++.dg/modules/timevar-1_b.C b/gcc/testsuite/g++.dg/modules/timevar-1_b.C
new file mode 100644 (file)
index 0000000..645f016
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/115165
+// { dg-additional-options "-fmodules-ts -ftime-report" }
+// { dg-allow-blank-lines-in-output 1 }
+// { dg-prune-output "Time variable" }
+// { dg-prune-output "\[0-9\]+%" }
+// { dg-prune-output "TOTAL" }
+// { dg-prune-output "checks" }
+
+import "timevar-1_a.H";
+X x;