[PATCH] D157684: [clang][ASTImporter] Repeated friend templates are partially imported
Ding Fei via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 11 01:08:53 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.
1. Repeated friends of template class/function in template class are partially imported:
template <class T>
class Container {
template <class U> friend void m();
template <class U> friend void m();
};
Only one `m` can be imported,
`FromTu`:
ClassTemplateDecl 0x5590cff47ae0 <input.cc:2:9, line:6:9> line:3:15 Container
|-TemplateTypeParmDecl 0x5590cff47990 <line:2:19, col:25> col:25 class depth 0 index 0 T
`-CXXRecordDecl 0x5590cff47a50 <line:3:9, line:6:9> line:3:15 class Container 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 0x5590cff47d30 <col:9, col:15> col:15 implicit class Container
|-FriendDecl 0x5590cff48048 <line:4:11, col:44> col:42
| `-FunctionTemplateDecl 0x5590cff47f80 parent 0x5590cfefeda8 <col:11, col:44> col:42 m
| |-TemplateTypeParmDecl 0x5590cff47dc0 <col:21, col:27> col:27 class depth 1 index 0 U
| `-FunctionDecl 0x5590cff47ec8 parent 0x5590cfefeda8 <col:30, col:44> col:42 m 'void ()'
`-FriendDecl 0x5590cff48260 <line:5:11, col:44> col:42
`-FunctionTemplateDecl 0x5590cff481f8 parent 0x5590cfefeda8 <col:11, col:44> col:42 m
|-TemplateTypeParmDecl 0x5590cff48088 <col:21, col:27> col:27 class depth 1 index 0 U
`-FunctionDecl 0x5590cff48140 parent 0x5590cfefeda8 <col:30, col:44> col:42 m 'void ()'
`ToTu`:
ClassTemplateDecl 0x5590cffe3ad8 <input.cc:2:9, line:6:9> line:3:15 Container
|-TemplateTypeParmDecl 0x5590cffe3950 <line:2:19, col:25> col:25 class depth 0 index 0 T
`-CXXRecordDecl 0x5590cffe3a10 <line:3:9, line:6:9> line:3:15 class Container 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 0x5590cffe3ef8 parent 0x5590cff9b128 <line:4:11, col:44> col:42 m // extranous node
| |-TemplateTypeParmDecl 0x5590cffe3d20 <col:21, col:27> col:27 class depth 1 index 0 U
| `-FunctionDecl 0x5590cffe3e28 parent 0x5590cff9b128 <col:30, col:44> col:42 m 'void ()'
|-FriendDecl 0x5590cffe3f60 <col:11, col:44> col:42
| `-FunctionTemplateDecl 0x5590cffe3ef8 parent 0x5590cff9b128 <col:11, col:44> col:42 m
| |-TemplateTypeParmDecl 0x5590cffe3d20 <col:21, col:27> col:27 class depth 1 index 0 U
| `-FunctionDecl 0x5590cffe3e28 parent 0x5590cff9b128 <col:30, col:44> col:42 m 'void ()'
`-CXXRecordDecl 0x5590cffe3fa0 <line:3:9, col:15> col:15 implicit class Container
Also note that an extranous `FunctionTemplateDecl 0x5590cffe3ef8` is added into this `ClassTemplateDecl 0x5590cffe3ad8` lexical context, which
renders it NOT identical to the original DeclContext, even after the second friend is successfully imported, this extra node would crash `clang-import-test`.
Plan to fix it in another revision.
2. Import single friend node `m` into existing context would crash with an assertion failure:
./build/tools/clang/unittests/AST/ASTTests --gtest_filter="*ImportFriendClasses.ImportOfRepeatedFriendFunctionTemplateDecl*" |& sed 's/danis/xxxxx/'
Note: Google Test filter = *ImportFriendClasses.ImportOfRepeatedFriendFunctionTemplateDecl*
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from ParameterizedTests/ImportFriendClasses
[ RUN ] ParameterizedTests/ImportFriendClasses.ImportOfRepeatedFriendFunctionTemplateDecl/0
ASTTests: /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ASTImporter.cpp:4139: clang::ExpectedDecl clang::ASTNodeImporter::VisitFriendDecl(clang::FriendDecl *): Assertion `ImportedEquivalentFriends.size() <= CountAndPosition.TotalCount && "Class with non-matching friends is imported, ODR check wrong?"' failed.
#0 0x00007f1f53bf812a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:602:11
#1 0x00007f1f53bf82db PrintStackTraceSignalHandler(void*) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:675:1
#2 0x00007f1f53bf6846 llvm::sys::RunSignalHandlers() /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Signals.cpp:104:5
#3 0x00007f1f53bf8af5 SignalHandler(int) /home/xxxxx/Sources/llvm-project-main/llvm/lib/Support/Unix/Signals.inc:413:1
#4 0x00007f1f5365afd0 (/lib/x86_64-linux-gnu/libc.so.6+0x3bfd0)
#5 0x00007f1f536a9d3c __pthread_kill_implementation ./nptl/./nptl/pthread_kill.c:44:76
#6 0x00007f1f5365af32 raise ./signal/../sysdeps/posix/raise.c:27:6
#7 0x00007f1f53645472 abort ./stdlib/./stdlib/abort.c:81:7
#8 0x00007f1f53645395 _nl_load_domain ./intl/./intl/loadmsgcat.c:1177:9
#9 0x00007f1f53653e32 (/lib/x86_64-linux-gnu/libc.so.6+0x34e32)
#10 0x00007f1f555c7179 clang::ASTNodeImporter::VisitFriendDecl(clang::FriendDecl*) /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ASTImporter.cpp:4140:7
#11 0x00007f1f5561f564 clang::declvisitor::Base<std::add_pointer, clang::ASTNodeImporter, llvm::Expected<clang::Decl*> >::Visit(clang::Decl*) /home/xxxxx/Sources/llvm-project-main/build/tools/clang/include/clang/AST/DeclNodes.inc:71:1
#12 0x00007f1f555eaf3d clang::ASTImporter::ImportImpl(clang::Decl*) /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ASTImporter.cpp:8768:19
#13 0x00007f1f555ce605 clang::ASTImporter::Import(clang::Decl*) /home/xxxxx/Sources/llvm-project-main/clang/lib/AST/ASTImporter.cpp:9167:8
#14 0x0000562aa520bd4a clang::ast_matchers::ASTImporterTestBase::TU::import(std::shared_ptr<clang::ASTImporterSharedState> const&, clang::ASTUnit*, clang::Decl*) /home/xxxxx/Sources/llvm-project-main/clang/unittests/AST/ASTImporterFixtures.cpp:83:12
#15 0x0000562aa520c9c9 clang::ast_matchers::ASTImporterTestBase::Import(clang::Decl*, clang::TestLanguage) /home/xxxxx/Sources/llvm-project-main/clang/unittests/AST/ASTImporterFixtures.cpp:199:9
#16 0x0000562aa531f023 clang::FriendDecl* clang::ast_matchers::ASTImporterTestBase::Import<clang::FriendDecl>(clang::FriendDecl*, clang::TestLanguage) /home/xxxxx/Sources/llvm-project-main/clang/unittests/AST/ASTImporterFixtures.h:185:32
#17 0x0000562aa52af6a2 clang::ast_matchers::ImportFriendClasses::testRepeatedFriendImport(char const*) /home/xxxxx/Sources/llvm-project-main/clang/unittests/AST/ASTImporterTest.cpp:4068:37
#18 0x0000562aa5255524 clang::ast_matchers::ImportFriendClasses_ImportOfRepeatedFriendFunctionTemplateDecl_Test::TestBody() /home/xxxxx/Sources/llvm-project-main/clang/unittests/AST/ASTImporterTest.cpp:4388:1
#19 0x00007f1f56ddb76b void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2433:3
#20 0x00007f1f56dc0e07 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2488:5
#21 0x00007f1f56da9963 testing::Test::Run() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2515:3
#22 0x00007f1f56daa1ba testing::TestInfo::Run() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2687:12
#23 0x00007f1f56daa71b testing::TestSuite::Run() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2815:44
#24 0x00007f1f56db2ef9 testing::internal::UnitTestImpl::RunAllTests() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:5337:24
#25 0x00007f1f56ddea3b bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2433:3
#26 0x00007f1f56dc3247 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:2488:5
#27 0x00007f1f56db2adf testing::UnitTest::Run() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/src/gtest.cc:4925:10
#28 0x00007f1f578add71 RUN_ALL_TESTS() /home/xxxxx/Sources/llvm-project-main/third-party/unittest/googletest/include/gtest/gtest.h:2472:3
#29 0x00007f1f578adcb4 main /home/xxxxx/Sources/llvm-project-main/third-party/unittest/UnitTestMain/TestMain.cpp:55:3
#30 0x00007f1f536461ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#31 0x00007f1f53646285 call_init ./csu/../csu/libc-start.c:128:20
#32 0x00007f1f53646285 __libc_start_main ./csu/../csu/libc-start.c:347:5
#33 0x0000562aa51aed31 _start (./build/tools/clang/unittests/AST/ASTTests+0x490d31)
`FriendCountAndPosition` computation for `FromContext` by pointer comparison is not reliable in this case.
As `ToContext` counts what's already imported, we could use `ASTStructuralEquivalence` which is more reliable.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D157684
Files:
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157684.549271.patch
Type: text/x-patch
Size: 7616 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230811/cf55a14e/attachment-0001.bin>
More information about the cfe-commits
mailing list