diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -297,6 +297,10 @@ not a type concept. - Fix crash when a doc comment contains a line splicing. (`#62054 `_) +- Work around with a clang coverage crash which happens when visiting + expressions/statements with invalid source locations in non-assert builds. + Assert builds may still see assertions triggered from this. + (`#62105 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -602,6 +602,19 @@ MostRecentLocation = *StartLoc; } + // If either of these locations is invalid, something elsewhere in the + // compiler has broken. + assert((!StartLoc || StartLoc->isValid()) && "Start location is not valid"); + assert((!EndLoc || EndLoc->isValid()) && "End location is not valid"); + + // However, we can still recover without crashing. + // If either location is invalid, set it to std::nullopt to avoid + // letting users of RegionStack think that region has a valid start/end + // location. + if (StartLoc && StartLoc->isInvalid()) + StartLoc = std::nullopt; + if (EndLoc && EndLoc->isInvalid()) + EndLoc = std::nullopt; RegionStack.emplace_back(Count, FalseCount, StartLoc, EndLoc); return RegionStack.size() - 1; @@ -624,7 +637,8 @@ assert(RegionStack.size() >= ParentIndex && "parent not in stack"); while (RegionStack.size() > ParentIndex) { SourceMappingRegion &Region = RegionStack.back(); - if (Region.hasStartLoc()) { + if (Region.hasStartLoc() && + (Region.hasEndLoc() || RegionStack[ParentIndex].hasEndLoc())) { SourceLocation StartLoc = Region.getBeginLoc(); SourceLocation EndLoc = Region.hasEndLoc() ? Region.getEndLoc() @@ -691,7 +705,7 @@ assert(SM.isWrittenInSameFile(Region.getBeginLoc(), EndLoc)); assert(SpellingRegion(SM, Region).isInSourceOrder()); SourceRegions.push_back(Region); - } + } RegionStack.pop_back(); } }