[clang] [clang][Coverage] Fix crash for nested macro in system headers (PR #181319)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 12 22:55:27 PST 2026


https://github.com/Nuullll created https://github.com/llvm/llvm-project/pull/181319

When compiling with coverage enabled, clang crashes if a file includes a system header that contains nested macro expansions.

The existing logic in `CoverageMappingBuilder::gatherFileIDs` attempts to remap locations from system macros by checking `SM.isInSystemMacro(Loc)`. This check is insufficient as it misses cases where a location's *spelling location* is still in a system header, such as with nested macros. This leads to the `!SM.isInSystemHeader(SM.getSpellingLoc(Loc))` assertion firing later on.

This patch fixes the issue by checking the spelling location anyway. It replaces the assertion with a check that skips any region whose spelling location is in a system header (when system header coverage is disabled). This correctly handles all cases, including nested macros.

>From 2f9b62c784b9d12ab0b4fde48862752f2d3efb1a Mon Sep 17 00:00:00 2001
From: Nuullll <vfirst218 at gmail.com>
Date: Fri, 13 Feb 2026 14:01:53 +0800
Subject: [PATCH] [clang][Coverage] Fix crash for nested macro in system
 headers

When compiling with coverage enabled, clang crashes if a file includes a
header via `-isystem` that contains macro expansions.

The existing logic in `CoverageMappingBuilder::gatherFileIDs` attempts to
remap locations from system macros by checking `SM.isInSystemMacro(Loc)`.
This check is insufficient as it misses cases where a location's *spelling
location* is still in a system header, such as with nested macros. This
leads to the `!SM.isInSystemHeader(SM.getSpellingLoc(Loc))` assertion
correctly firing later on.

This patch fixes the issue by checking the spelling location directly.
It replaces the problematic logic with a check that skips any region whose
spelling location is in a system header (when system header coverage is
disabled). This correctly handles all cases, including nested macros.
---
 clang/lib/CodeGen/CoverageMappingGen.cpp           | 10 ++++++++--
 clang/test/CoverageMapping/Inputs/nested.h         |  2 ++
 clang/test/CoverageMapping/system_nested_macro.cpp |  8 ++++++++
 3 files changed, 18 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CoverageMapping/Inputs/nested.h
 create mode 100644 clang/test/CoverageMapping/system_nested_macro.cpp

diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 803037d1874b3..82426d2893484 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -401,8 +401,14 @@ class CoverageMappingBuilder {
       if (!Visited.insert(File).second)
         continue;
 
-      assert(SystemHeadersCoverage ||
-             !SM.isInSystemHeader(SM.getSpellingLoc(Loc)));
+      // Ignore regions from system headers unless collecting coverage from
+      // system headers is explicitly enabled.
+      if (!SystemHeadersCoverage &&
+          SM.isInSystemHeader(SM.getSpellingLoc(Loc))) {
+        assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() &&
+               "Don't suppress the condition in system headers");
+        continue;
+      }
 
       unsigned Depth = 0;
       for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
diff --git a/clang/test/CoverageMapping/Inputs/nested.h b/clang/test/CoverageMapping/Inputs/nested.h
new file mode 100644
index 0000000000000..46c46242e1f73
--- /dev/null
+++ b/clang/test/CoverageMapping/Inputs/nested.h
@@ -0,0 +1,2 @@
+#define Y X
+Y
diff --git a/clang/test/CoverageMapping/system_nested_macro.cpp b/clang/test/CoverageMapping/system_nested_macro.cpp
new file mode 100644
index 0000000000000..ec73d2a69de5f
--- /dev/null
+++ b/clang/test/CoverageMapping/system_nested_macro.cpp
@@ -0,0 +1,8 @@
+// clang previously crashes when including nested macro from a system header.
+// REQUIRES: asserts
+// RUN: %clang -isystem %S/Inputs -fprofile-instr-generate -fcoverage-mapping -c %s
+
+int main() {
+#define X ;
+#include <nested.h>
+}



More information about the cfe-commits mailing list