The cppcoreguidelines-virtual-base-class-destructor checker crashed on this example:
#define DECLARE(CLASS) \ class CLASS { \ protected: \ virtual ~CLASS(); \ } DECLARE(Foo); // no-crash
The checker will hit the following assertion:
clang-tidy: llvm/include/llvm/ADT/Optional.h:196: T &llvm::optional_detail::OptionalStorage<clang::Token, true>::getValue() & [T = clang::Token]: Assertion `hasVal' failed."
It turns out, Lexer::findNextToken() returned llvm::None within the getVirtualKeywordRange() function when the VirtualEndLoc SourceLocation represents a macro expansion.
To prevent this from happening, I decided to propagate the llvm::None further up and only create the removal of virtual if the getVirtualKeywordRange() succeeds.
I considered an alternative fix for this issue:
I could have checked the Destructor.getLocation().isMacroID() before doing any Fixit calculation inside the check() function.
In contrast to this approach my patch will preserve the diagnostics and drop the fixits only if it would have crashed.
It is strange that there is no fix-it here even though the keyword appears as a single token ...[1]