Index: clang/lib/CodeGen/CoverageMappingGen.cpp =================================================================== --- clang/lib/CodeGen/CoverageMappingGen.cpp +++ clang/lib/CodeGen/CoverageMappingGen.cpp @@ -619,7 +619,14 @@ MostRecentLocation = getIncludeOrExpansionLoc(EndLoc); assert(SM.isWrittenInSameFile(Region.getBeginLoc(), EndLoc)); - assert(SpellingRegion(SM, Region).isInSourceOrder()); + + // FIXME: See llvm.org/PR39942. The clang preprocessor may not preserve + // the correct end location for conditional expressions. Hide coverage + // for such regions instead of crashing/asserting. This should be + // turned back into an assert. + if (!SpellingRegion(SM, Region).isInSourceOrder()) + Region.setEndLoc(Region.getBeginLoc()); + SourceRegions.push_back(Region); if (ParentOfDeferredRegion) { Index: clang/test/CoverageMapping/bad-coverage-for-condexpr-in-macro-pr39942.cpp =================================================================== --- /dev/null +++ clang/test/CoverageMapping/bad-coverage-for-condexpr-in-macro-pr39942.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name pr39942.cpp %s | FileCheck %s + +class a; +template a &operator<<(b &, const char *); +int c; +#define d(l) l(__FILE__, __LINE__, c) +#define COMPACT_GOOGLE_LOG_ERROR d(e) +#define f(g, condition) 0 ? (void)0 : h() & g +#define i(j) COMPACT_GOOGLE_LOG_##j.g() +#define k(j) f(i(j), ) +class e { +public: + e(const char *, int, int); + a &g(); +}; +class h { +public: + void operator&(a &); +}; +#define m(lib, func) \ +#func; \ + k(ERROR) << #func; \ + return 0 // CHECK: File 1, [[@LINE-1]]:4 -> [[@LINE-1]]:4 = (#0 - #1) +bool n() { m(, ); }