[PATCH] D157691: [ASTImporter] Remove extranous FunctionTemplateDecl introduced by templated friend

Ding Fei via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 11 02:12:27 PDT 2023


danix800 created this revision.
danix800 added reviewers: balazske, aaron.ballman.
danix800 added a project: clang.
Herald added subscribers: pengfei, martong, kristof.beyls.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: All.
danix800 requested review of this revision.
Herald added a subscriber: cfe-commits.

An extranous `FunctionTemplateDecl` is introduced in the following testcase:

  template <typename T> struct A {
    template <typename U> friend void f();
  };

`From`:

  ClassTemplateDecl 0x55dae7001500 <input.cc:1:1, col:73> col:30 A
  |-TemplateTypeParmDecl 0x55dae70013b0 <col:11, col:20> col:20 typename depth 0 index 0 T
  `-CXXRecordDecl 0x55dae7001470 <col:23, col:73> col:30 struct A definition
    |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
    | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
    | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
    | |-MoveConstructor exists simple trivial needs_implicit
    | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
    | |-MoveAssignment exists simple trivial needs_implicit
    | `-Destructor simple irrelevant trivial needs_implicit
    |-CXXRecordDecl 0x55dae7001750 <col:23, col:30> col:30 implicit struct A
    `-FriendDecl 0x55dae7001a68 <col:35, col:71> col:69
      `-FunctionTemplateDecl 0x55dae70019a0 parent 0x55dae6f97e28 <col:35, col:71> col:69 f
        |-TemplateTypeParmDecl 0x55dae70017e0 <col:45, col:54> col:54 typename depth 1 index 0 U
        `-FunctionDecl 0x55dae70018e8 parent 0x55dae6f97e28 <col:57, col:71> col:69 f 'void ()'

`To`:

  ClassTemplateDecl 0x55dae7116618 <input.cc:1:1, col:73> col:30 A
  |-TemplateTypeParmDecl 0x55dae7116490 <col:11, col:20> col:20 typename depth 0 index 0 T
  `-CXXRecordDecl 0x55dae7116550 <col:23, col:73> col:30 struct A definition
    |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
    | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
    | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
    | |-MoveConstructor exists simple trivial needs_implicit
    | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
    | |-MoveAssignment exists simple trivial needs_implicit
    | `-Destructor simple irrelevant trivial needs_implicit
    |-FunctionTemplateDecl 0x55dae7116a38 parent 0x55dae6fa2b68 <col:35, col:71> col:69 f                            // extranous node
    | |-TemplateTypeParmDecl 0x55dae7116860 <col:45, col:54> col:54 typename depth 1 index 0 U
    | `-FunctionDecl 0x55dae7116968 parent 0x55dae6fa2b68 <col:57, col:71> col:69 f 'void ()'
    |-FriendDecl 0x55dae7116aa0 <col:35, col:71> col:69
    | `-FunctionTemplateDecl 0x55dae7116a38 parent 0x55dae6fa2b68 <col:35, col:71> col:69 f
    |   |-TemplateTypeParmDecl 0x55dae7116860 <col:45, col:54> col:54 typename depth 1 index 0 U
    |   `-FunctionDecl 0x55dae7116968 parent 0x55dae6fa2b68 <col:57, col:71> col:69 f 'void ()'
    `-CXXRecordDecl 0x55dae7116ae0 <col:23, col:30> col:30 implicit struct A

`clang-import-test` would crash on this case:

  clang-import-test: /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ExternalASTMerger.cpp:533: auto clang::ExternalASTMerger::FindExternalLexicalDecls(const clang::DeclContext *, llvm::function_ref<bool (Decl::Kind)>, SmallVectorImpl<clang::Decl *> &)::(anonymous class)::operator()(clang::ASTImporter &, clang::ASTImporter &, Source<const clang::DeclContext *>) const: Assertion `!(*ImportedDeclOrErr) || IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC)' failed.
  f #0 0x00007fec39df812a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:602:11
   #1 0x00007fec39df82db PrintStackTraceSignalHandler(void*) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:675:1
   #2 0x00007fec39df6846 llvm::sys::RunSignalHandlers() /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Signals.cpp:104:5
   #3 0x00007fec39df8af5 SignalHandler(int) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:413:1
   #4 0x00007fec3985afd0 (/lib/x86_64-linux-gnu/libc.so.6+0x3bfd0)
   #5 0x00007fec398a9d3c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
   #6 0x00007fec3985af32 raise ./signal/../sysdeps/posix/raise.c:27:6
   #7 0x00007fec39845472 abort ./stdlib/abort.c:81:7
   #8 0x00007fec39845395 _nl_load_domain ./intl/loadmsgcat.c:1177:9
   #9 0x00007fec39853e32 (/lib/x86_64-linux-gnu/libc.so.6+0x34e32)
  #10 0x00007fec3c90c203 clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&)::$_5::operator()(clang::ASTImporter&, clang::ASTImporter&, (anonymous namespace)::Source<clang::DeclContext const*>) const /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ExternalASTMerger.cpp:532:11
  #11 0x00007fec3c9094a7 void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&)::$_5>(clang::DeclContext const*, clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&)::$_5) /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ExternalASTMerger.cpp:283:3
  #12 0x00007fec3c9093e1 clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&) /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ExternalASTMerger.cpp:540:1
  #13 0x00007fec3c6e6262 clang::ExternalASTSource::FindExternalLexicalDecls(clang::DeclContext const*, llvm::SmallVectorImpl<clang::Decl*>&) /home/xxxxx/Sources/llvm-project-main/clang/include/clang/AST/ExternalASTSource.h:186:3
  #14 0x00007fec3c6e1d14 clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/DeclBase.cpp:1446:7
  #15 0x00007fec3c6e218f clang::DeclContext::decls_begin() const /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/DeclBase.cpp:0:5
  #16 0x00007fec3275b7c9 clang::DeclContext::decls() const /home/xxxxx/Sources/llvm-project-main/clang/include/clang/AST/DeclBase.h:2206:48
  #17 0x00007fec33d4c04e clang::Sema::InstantiateClass(clang::SourceLocation, clang::CXXRecordDecl*, clang::CXXRecordDecl*, clang::MultiLevelTemplateArgumentList const&, clang::TemplateSpecializationKind, bool) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaTemplateInstantiate.cpp:3239:32
  #18 0x00007fec33d4d7b9 clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation, clang::ClassTemplateSpecializationDecl*, clang::TemplateSpecializationKind, bool) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaTemplateInstantiate.cpp:3740:3
  #19 0x00007fec33f0a038 clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*)::$_3::operator()() const /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaType.cpp:9268:23
  #20 0x00007fec33f09fe5 void llvm::function_ref<void ()>::callback_fn<clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*)::$_3>(long) /home/xxxxx/Sources/llvm-project-main/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:5
  #21 0x00007fec329104a9 llvm::function_ref<void ()>::operator()() const /home/xxxxx/Sources/llvm-project-main/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:5
  #22 0x00007fec328f61dd clang::runWithSufficientStackSpace(llvm::function_ref<void ()>, llvm::function_ref<void ()>) /home/xxxxx/Sources/llvm-project-main/clang/include/clang/Basic/Stack.h:52:3
  #23 0x00007fec328e2230 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/Sema.cpp:513:1
  #24 0x00007fec33eeb714 clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaType.cpp:9272:22
  #25 0x00007fec33eeaff3 clang::Sema::RequireCompleteType(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser&) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaType.cpp:8992:7
  #26 0x00007fec33eec333 clang::Sema::RequireCompleteType(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, unsigned int) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaType.cpp:9337:10
  #27 0x00007fec328f884d clang::Sema::RequireCompleteType(clang::SourceLocation, clang::QualType, unsigned int) /home/xxxxx/Sources/llvm-project-main/clang/include/clang/Sema/Sema.h:2532:5
  #28 0x00007fec32dd1518 clang::Sema::ActOnUninitializedDecl(clang::Decl*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Sema/SemaDecl.cpp:13962:11
  #29 0x00007fec3dd0f188 clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseDecl.cpp:0:13
  #30 0x00007fec3dd0d083 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseDecl.cpp:2264:9
  #31 0x00007fec3dd0c0ad clang::Parser::ParseSimpleDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, bool, clang::Parser::ForRangeInit*, clang::SourceLocation*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseDecl.cpp:1957:10
  #32 0x00007fec3dd0bc69 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseDecl.cpp:1881:12
  #33 0x00007fec3de16da9 clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseStmt.cpp:249:16
  #34 0x00007fec3de1670b clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseStmt.cpp:117:20
  #35 0x00007fec3de1f51e clang::Parser::ParseCompoundStatementBody(bool) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseStmt.cpp:1205:11
  #36 0x00007fec3de20c24 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseStmt.cpp:2468:21
  #37 0x00007fec3de4b2df clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:1475:3
  #38 0x00007fec3dd0cc5b clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseDecl.cpp:2199:27
  #39 0x00007fec3de4a151 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:1214:10
  #40 0x00007fec3de4963f clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:1229:12
  #41 0x00007fec3de48f04 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:1040:14
  #42 0x00007fec3de46dcc clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:742:12
  #43 0x00007fec3de464c0 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/Parser.cpp:594:8
  #44 0x00007fec3dcea898 clang::ParseAST(clang::Sema&, bool, bool) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseAST.cpp:162:15
  #45 0x00007fec3dcea6b8 clang::ParseAST(clang::Preprocessor&, clang::ASTConsumer*, clang::ASTContext&, bool, clang::TranslationUnitKind, clang::CodeCompleteConsumer*, bool) /home/xxxxx/Sources/llvm-project-main/clang/lib/Parse/ParseAST.cpp:113:1
  #46 0x000055c2677c497e (anonymous namespace)::ParseSource(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, clang::CompilerInstance&, clang::ASTConsumer&) /home/xxxxx/Sources/llvm-project-main/clang/tools/clang-import-test/clang-import-test.cpp:302:10
  #47 0x000055c2677c3d07 (anonymous namespace)::Parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, llvm::MutableArrayRef<(anonymous namespace)::CIAndOrigins>, bool, bool) /home/xxxxx/Sources/llvm-project-main/clang/tools/clang-import-test/clang-import-test.cpp:335:19
  #48 0x000055c2677c382b main /home/xxxxx/Sources/llvm-project-main/clang/tools/clang-import-test/clang-import-test.cpp:384:29
  #49 0x00007fec398461ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
  #50 0x00007fec39846285 call_init ./csu/../csu/libc-start.c:128:20
  #51 0x00007fec39846285 __libc_start_main ./csu/../csu/libc-start.c:347:5
  #52 0x000055c2677c29f1 _start (/home/xxxxx/Sources/llvm-project-main//build/bin/clang-import-test+0x279f1)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157691

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Import/templated-friend/Inputs/T.cpp
  clang/test/Import/templated-friend/test.cpp


Index: clang/test/Import/templated-friend/test.cpp
===================================================================
--- /dev/null
+++ clang/test/Import/templated-friend/test.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-import-test -import %S/Inputs/T.cpp -expression %s
+
+void expr() {
+  A<int> a;
+}
Index: clang/test/Import/templated-friend/Inputs/T.cpp
===================================================================
--- /dev/null
+++ clang/test/Import/templated-friend/Inputs/T.cpp
@@ -0,0 +1,3 @@
+template <typename T> struct A {
+  template <typename U> friend void f();
+};
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -6447,7 +6447,8 @@
 
   ToFunc->setAccess(D->getAccess());
   ToFunc->setLexicalDeclContext(LexicalDC);
-  LexicalDC->addDeclInternal(ToFunc);
+  if (D->getFriendObjectKind() == Decl::FOK_None)
+    LexicalDC->addDeclInternal(ToFunc);
 
   ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable();
   if (LT && !OldParamDC.empty()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157691.549291.patch
Type: text/x-patch
Size: 1102 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230811/dee43f4c/attachment.bin>


More information about the cfe-commits mailing list