From: Nathaniel Shead Date: Sun, 7 Jul 2024 13:19:52 +0000 (+1000) Subject: c++/modules: Conditionally start timer during lazy load [PR115165] X-Git-Tag: basepoints/gcc-16~7432 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7b2434cc7e712dc5055bde02c441393ae881f06;p=thirdparty%2Fgcc.git c++/modules: Conditionally start timer during lazy load [PR115165] 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 --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index d385b422168..69764fd772d 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -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 index 00000000000..efd7f0ecced --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/timevar-1_a.H @@ -0,0 +1,14 @@ +// PR c++/115165 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template struct A { virtual ~A(); }; +struct B : A {}; +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 index 00000000000..645f01697eb --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/timevar-1_b.C @@ -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;