[clang] e3ebeec - [Coverage] Skip coverage mapping for consteval member functions (#190870)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 23 03:16:31 PDT 2026


Author: Paweł Bylica
Date: 2026-04-23T12:16:25+02:00
New Revision: e3ebeeca9531d2e29196f16ec31c96cbc683d3e2

URL: https://github.com/llvm/llvm-project/commit/e3ebeeca9531d2e29196f16ec31c96cbc683d3e2
DIFF: https://github.com/llvm/llvm-project/commit/e3ebeeca9531d2e29196f16ec31c96cbc683d3e2.diff

LOG: [Coverage] Skip coverage mapping for consteval member functions (#190870)

Static consteval member functions were incorrectly getting a coverage
mapping with zero count, making them appear as uncovered lines. Free
consteval functions were already correctly excluded because
EmitTopLevelDecl returns early for immediate functions.

The fix adds an isImmediateFunction() check in
HandleInlineMemberFunction before adding deferred coverage mappings,
consistent with the top-level check.

Fixes #164448.

Added: 
    clang/test/CoverageMapping/consteval.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/CodeGen/ModuleBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8d60450f54669..03362cf4e0f8a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -460,6 +460,8 @@ Improvements to Coverage Mapping
 - [MC/DC] Nested expressions are handled as individual MC/DC expressions.
 - "Single byte coverage" now supports branch coverage and can be used
   together with ``-fcoverage-mcdc``.
+- Consteval member functions are no longer emitted in coverage mappings,
+  matching the existing behavior for free consteval functions. (#GH164448)
 
 Bug Fixes in This Version
 -------------------------

diff  --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index dd6b3c904d03d..1888de4521abd 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -228,8 +228,9 @@ namespace {
 
       // Provide some coverage mapping even for methods that aren't emitted.
       // Don't do this for templated classes though, as they may not be
-      // instantiable.
-      if (!D->getLexicalDeclContext()->isDependentContext())
+      // instantiable. Also skip consteval methods as they are never emitted.
+      if (!D->getLexicalDeclContext()->isDependentContext() &&
+          !D->getAsFunction()->isImmediateFunction())
         Builder->AddDeferredUnusedCoverageMapping(D);
     }
 

diff  --git a/clang/test/CoverageMapping/consteval.cpp b/clang/test/CoverageMapping/consteval.cpp
new file mode 100644
index 0000000000000..3540d52011955
--- /dev/null
+++ b/clang/test/CoverageMapping/consteval.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -std=c++20 -triple %itanium_abi_triple -main-file-name consteval.cpp %s | FileCheck %s
+
+// Consteval functions should not have coverage mappings, as they are evaluated
+// entirely at compile time and produce no runtime code.
+// See https://github.com/llvm/llvm-project/issues/164448.
+
+// CHECK-NOT: _Z1gv:
+consteval int g() { return 0; }
+
+struct S {
+  // CHECK-NOT: _ZN1S1sEv:
+  static consteval int s() { return 1; }
+};
+
+// CHECK-LABEL: main:
+// CHECK-NEXT: File 0, [[@LINE+1]]:12 -> [[@LINE+5]]:2 = #0
+int main() {
+  [[maybe_unused]] auto i = g();
+  [[maybe_unused]] auto j = S::s();
+  return 0;
+}


        


More information about the cfe-commits mailing list