[clang][AST] Fix AST IgnoreUnlessSpelledInSource traversal nullptr dereference (#146103)
In summary dumping a `catch(...)` statement using IgnoreUnlessSpelledInSource AST traversal causes a seg fault, as the variable declaration of the catch is `nullptr`. Diagnosed the cause by attaching the debugger to `clang-query`, this PR adds a fix to check for `nullptr` before accessing the `isImplicit()` method of the `Decl` pointee in the AST node traverser visitor Fixes #146101
This commit is contained in:
committed by
GitHub
parent
1cdc7f8724
commit
44ec3e8f9c
@@ -903,6 +903,7 @@ Bug Fixes to AST Handling
|
|||||||
- Fixed dependency calculation for TypedefTypes (#GH89774)
|
- Fixed dependency calculation for TypedefTypes (#GH89774)
|
||||||
- The ODR checker now correctly hashes the names of conversion operators. (#GH143152)
|
- The ODR checker now correctly hashes the names of conversion operators. (#GH143152)
|
||||||
- Fixed the right parenthesis source location of ``CXXTemporaryObjectExpr``. (#GH143711)
|
- Fixed the right parenthesis source location of ``CXXTemporaryObjectExpr``. (#GH143711)
|
||||||
|
- Fixed a crash when performing an ``IgnoreUnlessSpelledInSource`` traversal of ASTs containing ``catch(...)`` statements. (#GH146103)
|
||||||
|
|
||||||
Miscellaneous Bug Fixes
|
Miscellaneous Bug Fixes
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
TraversalKind GetTraversalKind() const { return Traversal; }
|
TraversalKind GetTraversalKind() const { return Traversal; }
|
||||||
|
|
||||||
void Visit(const Decl *D, bool VisitLocs = false) {
|
void Visit(const Decl *D, bool VisitLocs = false) {
|
||||||
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit())
|
if (Traversal == TK_IgnoreUnlessSpelledInSource && D && D->isImplicit())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
getNodeDelegate().AddChild([=] {
|
getNodeDelegate().AddChild([=] {
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ public:
|
|||||||
: TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
|
: TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
|
||||||
|
|
||||||
void Visit(const Decl *D) {
|
void Visit(const Decl *D) {
|
||||||
|
if (!D) {
|
||||||
|
OS << "<<<NULL>>>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
OS << D->getDeclKindName() << "Decl";
|
OS << D->getDeclKindName() << "Decl";
|
||||||
if (auto *ND = dyn_cast<NamedDecl>(D)) {
|
if (auto *ND = dyn_cast<NamedDecl>(D)) {
|
||||||
OS << " '" << ND->getDeclName() << "'";
|
OS << " '" << ND->getDeclName() << "'";
|
||||||
@@ -1932,4 +1936,75 @@ CXXRewrittenBinaryOperator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Traverse, CatchStatements) {
|
||||||
|
|
||||||
|
auto AST = buildASTFromCode(R"cpp(
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
}
|
||||||
|
catch (const int&)
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)cpp");
|
||||||
|
|
||||||
|
auto BN =
|
||||||
|
ast_matchers::match(cxxCatchStmt().bind("catch"), AST->getASTContext());
|
||||||
|
EXPECT_EQ(BN.size(), 2u);
|
||||||
|
const auto *catchWithoutDecl = BN[0].getNodeAs<Stmt>("catch");
|
||||||
|
|
||||||
|
llvm::StringRef Expected = R"cpp(
|
||||||
|
CXXCatchStmt
|
||||||
|
|-<<<NULL>>>
|
||||||
|
`-CompoundStmt
|
||||||
|
`-DeclStmt
|
||||||
|
`-VarDecl 'b'
|
||||||
|
)cpp";
|
||||||
|
EXPECT_EQ(dumpASTString(TK_AsIs, catchWithoutDecl), Expected);
|
||||||
|
|
||||||
|
Expected = R"cpp(
|
||||||
|
CXXCatchStmt
|
||||||
|
|-<<<NULL>>>
|
||||||
|
`-CompoundStmt
|
||||||
|
`-DeclStmt
|
||||||
|
`-VarDecl 'b'
|
||||||
|
)cpp";
|
||||||
|
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, catchWithoutDecl),
|
||||||
|
Expected);
|
||||||
|
|
||||||
|
const auto *catchWithDecl = BN[1].getNodeAs<Stmt>("catch");
|
||||||
|
|
||||||
|
Expected = R"cpp(
|
||||||
|
CXXCatchStmt
|
||||||
|
|-VarDecl ''
|
||||||
|
`-CompoundStmt
|
||||||
|
`-DeclStmt
|
||||||
|
`-VarDecl 'b'
|
||||||
|
)cpp";
|
||||||
|
EXPECT_EQ(dumpASTString(TK_AsIs, catchWithDecl), Expected);
|
||||||
|
|
||||||
|
Expected = R"cpp(
|
||||||
|
CXXCatchStmt
|
||||||
|
|-VarDecl ''
|
||||||
|
`-CompoundStmt
|
||||||
|
`-DeclStmt
|
||||||
|
`-VarDecl 'b'
|
||||||
|
)cpp";
|
||||||
|
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, catchWithDecl),
|
||||||
|
Expected);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace clang
|
} // namespace clang
|
||||||
|
|||||||
Reference in New Issue
Block a user