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 <[email protected]> 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> +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
