Clang using RefactoringTool with including transformer and ASTMatcher causes ASAN use-after-poison

Hi, I’m now writing some auto-refactoring tools for C, and I encountered the AddressSanitizer: use-after-poison.
But I don’t know why this happens in my case.
The following is the reduced reproductive program, I just used SyntaxOnlyAction like libTooling tutorial. (I want to use ASTMatchFinder instead of SyntaxOnlyAction.

#include "Mutator/VecMutator.h"
#include <clang/AST/ASTContext.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Refactoring.h>
#include <clang/Tooling/Transformer/RangeSelector.h>
#include <clang/Tooling/Transformer/RewriteRule.h>
#include <clang/Tooling/Transformer/Stencil.h>
#include <llvm/Support/CommandLine.h>
#include <string>

using namespace std;
using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace clang::transformer;
using namespace clang::transformer::detail;
using namespace llvm;


static cl::OptionCategory VecMutOptCategory("vecmut options");

int main(int argc, const char **argv) {
  llvm::Expected<CommonOptionsParser> Expected =
      CommonOptionsParser::create(argc, argv, VecMutOptCategory);
  if (!Expected) {
    llvm::errs() << Expected.takeError();
    return 1;
  }
  CommonOptionsParser &OptionsParser = Expected.get();

  RefactoringTool Tool(OptionsParser.getCompilations(),
                       OptionsParser.getSourcePathList());

  return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());;

}

and ASAN says

=================================================================
==619268==ERROR: AddressSanitizer: use-after-poison on address 0x521000061960 at pc 0x5623cef91e5a bp 0x7fff32f64eb0 sp 0x7fff32f64670
READ of size 8 at 0x521000061960 thread T0
    #0 0x5623cef91e59 in __asan_memcpy (/home/khei4/git/VecFuzz/build/bin/vecmut+0x588e59) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #1 0x5623cf01bf60 in llvm::detail::PunnedPointer<void*>::asInt() const /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:41:5
    #2 0x5623cf01bdf8 in llvm::detail::PunnedPointer<void*>::operator long() const /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:45:48
    #3 0x5623cf03d4e8 in llvm::PointerIntPair<void*, 1u, int, llvm::pointer_union_detail::PointerUnionUIntTraits<clang::DeclContext*, clang::Decl::MultipleDC*>, llvm::PointerIntPairInfo<void*, 1u, llvm::pointer_union_detail::PointerUnionUIntTraits<clang::DeclContext*, clang::Decl::MultipleDC*>>>::getInt() const /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:96:57
    #4 0x5623cf03d452 in bool llvm::CastInfoPointerUnionImpl<clang::DeclContext*, clang::Decl::MultipleDC*>::isPossible<clang::DeclContext*>(llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>&) /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:230:18
    #5 0x5623cf03d3a0 in llvm::CastInfo<clang::DeclContext*, llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>, void>::isPossible(llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>&) /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:248:12
    #6 0x5623cf03d340 in llvm::ConstStrippingForwardingCast<clang::DeclContext*, llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*> const, llvm::CastInfo<clang::DeclContext*, llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>, void>>::isPossible(llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*> const&) /home/khei4/git/llvm-project/llvm/include/llvm/Support/Casting.h:396:12
    #7 0x5623cf03d2e0 in bool llvm::isa<clang::DeclContext*, llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>>(llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*> const&) /home/khei4/git/llvm-project/llvm/include/llvm/Support/Casting.h:549:10
    #8 0x5623cf03d278 in bool llvm::PointerUnion<clang::DeclContext*, clang::Decl::MultipleDC*>::is<clang::DeclContext*>() const /home/khei4/git/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:150:57
    #9 0x5623cf03d0d0 in clang::Decl::isInSemaDC() const /home/khei4/git/llvm-project/clang/include/clang/AST/DeclBase.h:272:44
    #10 0x5623cf03cf88 in clang::Decl::getLexicalDeclContext() /home/khei4/git/llvm-project/clang/include/clang/AST/DeclBase.h:897:9
    #11 0x5623d07de477 in clang::DeclContext::addHiddenDecl(clang::Decl*) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x1dd5477) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #12 0x5623d07e557c in clang::DeclContext::addDecl(clang::Decl*) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x1ddc57c) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #13 0x5623cfadca7c in clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x10d3a7c) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #14 0x5623cf9045c2 in clang::Sema::Initialize() (/home/khei4/git/VecFuzz/build/bin/vecmut+0xefb5c2) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #15 0x5623cf624223 in clang::Parser::Initialize() (/home/khei4/git/VecFuzz/build/bin/vecmut+0xc1b223) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #16 0x5623cf61d02e in clang::ParseAST(clang::Sema&, bool, bool) (/home/khei4/git/VecFuzz/build/bin/vecmut+0xc1402e) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #17 0x5623cf368968 in clang::FrontendAction::Execute() (/home/khei4/git/VecFuzz/build/bin/vecmut+0x95f968) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #18 0x5623cf2e4a1d in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x8dba1d) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #19 0x5623cf1cf5ef in clang::tooling::FrontendActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x7c65ef) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #20 0x5623cf1c6566 in clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, std::shared_ptr<clang::CompilerInvocation>, std::shared_ptr<clang::PCHContainerOperations>) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x7bd566) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #21 0x5623cf1ca4d7 in clang::tooling::ToolInvocation::run() (/home/khei4/git/VecFuzz/build/bin/vecmut+0x7c14d7) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #22 0x5623cf1cda71 in clang::tooling::ClangTool::run(clang::tooling::ToolAction*) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x7c4a71) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #23 0x5623cefd3103 in main /home/khei4/git/VecFuzz/tools/vecmut/vecmut.cpp:39:15
    #24 0x145ea21c1082 in __libc_start_main /build/glibc-BHL3KM/glibc-2.31/csu/../csu/libc-start.c:308:16
    #25 0x5623ceef8cdd in _start (/home/khei4/git/VecFuzz/build/bin/vecmut+0x4efcdd) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)

0x521000061960 is located 96 bytes inside of 4096-byte region [0x521000061900,0x521000062900)
allocated by thread T0 here:
    #0 0x5623cefd0c32 in operator new(unsigned long, std::align_val_t) (/home/khei4/git/VecFuzz/build/bin/vecmut+0x5c7c32) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)
    #1 0x5623cf01fcd5 in llvm::MallocAllocator::Allocate(unsigned long, unsigned long) /home/khei4/git/llvm-project/llvm/include/llvm/Support/AllocatorBase.h:92:12
    #2 0x5623cf02050b in llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 4096ul, 4096ul, 128ul>::StartNewSlab() /home/khei4/git/llvm-project/llvm/include/llvm/Support/Allocator.h:339:42
    #3 0x5623cf01f432 in llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 4096ul, 4096ul, 128ul>::Allocate(unsigned long, llvm::Align) /home/khei4/git/llvm-project/llvm/include/llvm/Support/Allocator.h:195:5
    #4 0x5623d0679cac in clang::ASTContext::getPointerType(clang::QualType) const (/home/khei4/git/VecFuzz/build/bin/vecmut+0x1c70cac) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3)

SUMMARY: AddressSanitizer: use-after-poison (/home/khei4/git/VecFuzz/build/bin/vecmut+0x588e59) (BuildId: ecb17952fdcae58cdf822b79c09bbc98cb8daca3) in __asan_memcpy
Shadow bytes around the buggy address:
  0x521000061680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x521000061700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x521000061780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x521000061800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x521000061880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x521000061900: 00 00 00 00 00 00 f7 00 00 04 f7 f7[f7]f7 f7 f7
  0x521000061980: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x521000061a00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x521000061a80: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x521000061b00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x521000061b80: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==619268==ABORTING

But it seems like not including clang transformer and ASTMatcher prevents this.

#include "Mutator/VecMutator.h"
#include <clang/AST/ASTContext.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Refactoring.h>
#include <llvm/Support/CommandLine.h>
#include <string>

using namespace std;
using namespace clang;
using namespace clang::tooling;
using namespace llvm;

I’m on Ubuntu 20.04.6 LTS, using released clang++ 17 installed by https://apt.llvm.org/llvm.sh and using llvm 18 d199ff17659fc65a9b1b4ebe2d304cdbfdfe89d7 built.

$ clang++-17 --version
Ubuntu clang version 17.0.4 (++20231031083147+309d55140c46-1~exp1~20231031083252.61)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

Is this a wrong way to use RefactoringTool?
Thanks!

I didn’t bisect commits, but on 3b905a0be5084f39d2f6fc06a18cb2053f4d802b this seems like to be fixed.