llvm-project/clang/unittests/AST
Gabor Marton a5e6590b15 [ASTImporter] Support CXXDeductionGuideDecl with local typedef
CXXDeductionGuideDecl with a local typedef has its own copy of the
TypedefDecl with the CXXDeductionGuideDecl as the DeclContext of that
TypedefDecl.
```
      template <typename T> struct A {
        typedef T U;
        A(U, T);
      };
      A a{(int)0, (int)0};
```
Related discussion on cfe-dev:
http://lists.llvm.org/pipermail/cfe-dev/2020-November/067252.html

Without this fix, when we import the CXXDeductionGuideDecl (via
VisitFunctionDecl) then before creating the Decl we must import the
FunctionType. However, the first parameter's type is the afore mentioned
local typedef. So, we then start importing the TypedefDecl whose
DeclContext is the CXXDeductionGuideDecl itself. The infinite loop is
formed.
```
 #0 clang::ASTNodeImporter::VisitCXXDeductionGuideDecl(clang::CXXDeductionGuideDecl*) clang/lib/AST/ASTImporter.cpp:3543:0
 #1 clang::declvisitor::Base<std::add_pointer, clang::ASTNodeImporter, llvm::Expected<clang::Decl*> >::Visit(clang::Decl*) /home/egbomrt/WORK/llvm5/build/debug/tools/clang/include/clang/AST/DeclNodes.inc:405:0
 #2 clang::ASTImporter::ImportImpl(clang::Decl*) clang/lib/AST/ASTImporter.cpp:8038:0
 #3 clang::ASTImporter::Import(clang::Decl*) clang/lib/AST/ASTImporter.cpp:8200:0
 #4 clang::ASTImporter::ImportContext(clang::DeclContext*) clang/lib/AST/ASTImporter.cpp:8297:0
 #5 clang::ASTNodeImporter::ImportDeclContext(clang::Decl*, clang::DeclContext*&, clang::DeclContext*&) clang/lib/AST/ASTImporter.cpp:1852:0
 #6 clang::ASTNodeImporter::ImportDeclParts(clang::NamedDecl*, clang::DeclContext*&, clang::DeclContext*&, clang::DeclarationName&, clang::NamedDecl*&, clang::SourceLocation&) clang/lib/AST/ASTImporter.cpp:1628:0
 #7 clang::ASTNodeImporter::VisitTypedefNameDecl(clang::TypedefNameDecl*, bool) clang/lib/AST/ASTImporter.cpp:2419:0
 #8 clang::ASTNodeImporter::VisitTypedefDecl(clang::TypedefDecl*) clang/lib/AST/ASTImporter.cpp:2500:0
 #9 clang::declvisitor::Base<std::add_pointer, clang::ASTNodeImporter, llvm::Expected<clang::Decl*> >::Visit(clang::Decl*) /home/egbomrt/WORK/llvm5/build/debug/tools/clang/include/clang/AST/DeclNodes.inc:315:0
 #10 clang::ASTImporter::ImportImpl(clang::Decl*) clang/lib/AST/ASTImporter.cpp:8038:0
 #11 clang::ASTImporter::Import(clang::Decl*) clang/lib/AST/ASTImporter.cpp:8200:0
 #12 llvm::Expected<clang::TypedefNameDecl*> clang::ASTNodeImporter::import<clang::TypedefNameDecl>(clang::TypedefNameDecl*) clang/lib/AST/ASTImporter.cpp:165:0
 #13 clang::ASTNodeImporter::VisitTypedefType(clang::TypedefType const*) clang/lib/AST/ASTImporter.cpp:1304:0
 #14 clang::TypeVisitor<clang::ASTNodeImporter, llvm::Expected<clang::QualType> >::Visit(clang::Type const*) /home/egbomrt/WORK/llvm5/build/debug/tools/clang/include/clang/AST/TypeNodes.inc:74:0
 #15 clang::ASTImporter::Import(clang::QualType) clang/lib/AST/ASTImporter.cpp:8071:0
 #16 llvm::Expected<clang::QualType> clang::ASTNodeImporter::import<clang::QualType>(clang::QualType const&) clang/lib/AST/ASTImporter.cpp:179:0
 #17 clang::ASTNodeImporter::VisitFunctionProtoType(clang::FunctionProtoType const*) clang/lib/AST/ASTImporter.cpp:1244:0
 #18 clang::TypeVisitor<clang::ASTNodeImporter, llvm::Expected<clang::QualType> >::Visit(clang::Type const*) /home/egbomrt/WORK/llvm5/build/debug/tools/clang/include/clang/AST/TypeNodes.inc:47:0
 #19 clang::ASTImporter::Import(clang::QualType) clang/lib/AST/ASTImporter.cpp:8071:0
 #20 llvm::Expected<clang::QualType> clang::ASTNodeImporter::import<clang::QualType>(clang::QualType const&) clang/lib/AST/ASTImporter.cpp:179:0
 #21 clang::QualType clang::ASTNodeImporter::importChecked<clang::QualType>(llvm::Error&, clang::QualType const&) clang/lib/AST/ASTImporter.cpp:198:0
 #22 clang::ASTNodeImporter::VisitFunctionDecl(clang::FunctionDecl*) clang/lib/AST/ASTImporter.cpp:3313:0
 #23 clang::ASTNodeImporter::VisitCXXDeductionGuideDecl(clang::CXXDeductionGuideDecl*) clang/lib/AST/ASTImporter.cpp:3543:0
```

The fix is to first create the TypedefDecl and only then start to import
the DeclContext.
Basically, we could do this during the import of all other Decls (not
just for typedefs). But it seems, there is only one another AST
construct that has a similar cycle: a struct defined as a function
parameter:
```
int struct_in_proto(struct data_t{int a;int b;} *d);

```
In that case, however, we had decided to return simply with an error
back then because that seemed to be a very rare construct.

Differential Revision: https://reviews.llvm.org/D92209
2020-12-09 21:25:04 +01:00
..
ASTContextParentMapTest.cpp Remove clang::ast_type_traits namespace in favor of clang 2020-02-13 10:46:47 -08:00
ASTImporterFixtures.cpp Rename APIs in unittests/AST/Language.h in preparation to share them 2020-05-29 14:25:20 +02:00
ASTImporterFixtures.h [ASTImporter] Refactor ASTImporter to support custom downstream tests 2020-07-21 10:34:17 -05:00
ASTImporterGenericRedeclTest.cpp Renamed Lang_C to Lang_C99, Lang_CXX to Lang_CXX03, and 2a to 20 2020-06-02 16:31:20 +02:00
ASTImporterODRStrategiesTest.cpp Renamed Lang_C to Lang_C99, Lang_CXX to Lang_CXX03, and 2a to 20 2020-06-02 16:31:20 +02:00
ASTImporterTest.cpp [ASTImporter] Support CXXDeductionGuideDecl with local typedef 2020-12-09 21:25:04 +01:00
ASTImporterVisibilityTest.cpp Rename APIs in unittests/AST/Language.h in preparation to share them 2020-05-29 14:25:20 +02:00
ASTPrint.h [clang][OpeMP] Model OpenMP structured-block in AST (PR40563) 2019-03-20 16:32:36 +00:00
ASTTraverserTest.cpp Remove unportable test 2020-11-18 12:42:07 +00:00
ASTTypeTraitsTest.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
ASTVectorTest.cpp Add some missing header dependencies 2020-02-27 14:32:12 -08:00
CMakeLists.txt Revert "[clang] Prevent that Decl::dump on a CXXRecordDecl deserialises further declarations." 2020-09-07 14:50:13 +02:00
CommentLexer.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
CommentParser.cpp [AST] Fixed string list in test 2020-08-09 23:17:48 +02:00
CommentTextTest.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
DataCollectionTest.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
DeclMatcher.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
DeclPrinterTest.cpp [clang] Add -fno-delayed-template-parsing to the added unit tests in DeclPrinterTest.cpp 2020-08-05 14:13:05 +01:00
DeclTest.cpp Added 'const' as suggested by ClangTidy llvm-qualified-auto 2020-03-13 11:49:23 +01:00
EvaluateAsRValueTest.cpp [Tooling] Migrated APIs that take ownership of objects to unique_ptr 2019-08-30 09:29:34 +00:00
ExternalASTSourceTest.cpp ArrayRef'ized CompilerInvocation::CreateFromArgs 2019-08-27 22:13:31 +00:00
MatchVerifier.h [clang][NFC] Store a pointer to the ASTContext in ASTDumper and TextNodeDumper 2020-07-03 13:59:22 +01:00
NamedDeclPrinterTest.cpp [AST] Fix the PrintQualifiedName for ObjC instance variable in class extension. 2020-05-19 15:17:36 +02:00
RecursiveASTVisitorTest.cpp [Tooling] Migrated APIs that take ownership of objects to unique_ptr 2019-08-30 09:29:34 +00:00
SizelessTypesTest.cpp [llvm][SveEmitter] Emit the bfloat version of `svld1ro`. 2020-06-18 16:36:31 +00:00
SourceLocationTest.cpp Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen. 2020-07-10 21:31:16 -04:00
StmtPrinterTest.cpp Set traversal explicitly where needed in tests 2020-05-21 22:34:38 +01:00
StructuralEquivalenceTest.cpp [ASTImporter][AST] Fix structural equivalency crash on dependent FieldDecl 2020-10-05 14:06:09 +02:00