balazske created this revision. Herald added subscribers: steakhal, martong, gamesh411, Szelethus, dkrupp. Herald added a reviewer: a.sidorin. Herald added a reviewer: shafik. Herald added a project: All. balazske requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Function 'isAncestorDeclContextOf' was using 'ParentMapContext' for looking up parent of statement nodes. There may be cases (bugs?) with ParentMapContext when parents of specific statements are not found. This leads to 'ASTImporter' infinite import loops when function 'hasAutoReturnTypeDeclaredInside' returns false incorrectly. A real case was found but could not be reproduced with test code. Use of 'ParentMapContext' is now removed and changed to a more safe (currently) method by searching for declarations in statements and find parent of these declarations. The new code was tested on a number of projects and no related crash was found. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136684 Files: clang/lib/AST/ASTImporter.cpp Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -34,7 +34,6 @@ #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" -#include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" @@ -3237,16 +3236,19 @@ return false; } -// Returns true if the statement S has a parent declaration that has a -// DeclContext that is inside (or equal to) DC. In a specific use case if DC is -// a FunctionDecl, check if statement S resides in the body of the function. +// Check if there is a declaration that has 'DC' as parent context and is +// referenced from statement 'S' or one of its children. The search is done in +// BFS order through children of 'S'. static bool isAncestorDeclContextOf(const DeclContext *DC, const Stmt *S) { - ParentMapContext &ParentC = DC->getParentASTContext().getParentMapContext(); - DynTypedNodeList Parents = ParentC.getParents(*S); - while (!Parents.empty()) { - if (const Decl *PD = Parents.begin()->get<Decl>()) - return isAncestorDeclContextOf(DC, PD); - Parents = ParentC.getParents(*Parents.begin()); + SmallVector<const Stmt *> ToProcess; + ToProcess.push_back(S); + while (!ToProcess.empty()) { + const Stmt *CurrentS = ToProcess.pop_back_val(); + ToProcess.append(CurrentS->child_begin(), CurrentS->child_end()); + if (const auto *DeclRef = dyn_cast<DeclRefExpr>(CurrentS)) + if (const Decl *D = DeclRef->getDecl()) + if (isAncestorDeclContextOf(DC, D)) + return true; } return false; }
Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -34,7 +34,6 @@ #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" -#include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" @@ -3237,16 +3236,19 @@ return false; } -// Returns true if the statement S has a parent declaration that has a -// DeclContext that is inside (or equal to) DC. In a specific use case if DC is -// a FunctionDecl, check if statement S resides in the body of the function. +// Check if there is a declaration that has 'DC' as parent context and is +// referenced from statement 'S' or one of its children. The search is done in +// BFS order through children of 'S'. static bool isAncestorDeclContextOf(const DeclContext *DC, const Stmt *S) { - ParentMapContext &ParentC = DC->getParentASTContext().getParentMapContext(); - DynTypedNodeList Parents = ParentC.getParents(*S); - while (!Parents.empty()) { - if (const Decl *PD = Parents.begin()->get<Decl>()) - return isAncestorDeclContextOf(DC, PD); - Parents = ParentC.getParents(*Parents.begin()); + SmallVector<const Stmt *> ToProcess; + ToProcess.push_back(S); + while (!ToProcess.empty()) { + const Stmt *CurrentS = ToProcess.pop_back_val(); + ToProcess.append(CurrentS->child_begin(), CurrentS->child_end()); + if (const auto *DeclRef = dyn_cast<DeclRefExpr>(CurrentS)) + if (const Decl *D = DeclRef->getDecl()) + if (isAncestorDeclContextOf(DC, D)) + return true; } return false; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits