If one definition is currently being defined, we do not compare for
equality and we assume that the decls are equal.
Details
- Reviewers
a_sidorin a.sidorin shafik - Commits
- rG17d39677e015: [ASTImporter][Structural Eq] Check for isBeingDefined
rGdbb117acf295: [ASTImporter][Structural Eq] Check for isBeingDefined
rC347564: [ASTImporter][Structural Eq] Check for isBeingDefined
rL347564: [ASTImporter][Structural Eq] Check for isBeingDefined
rL345760: [ASTImporter][Structural Eq] Check for isBeingDefined
rC345760: [ASTImporter][Structural Eq] Check for isBeingDefined
Diff Detail
- Repository
- rC Clang
Event Timeline
Hi Gabor,
I wonder if it is possible to get into situation where non-equivalent decls are marked equivalent with this patch? If yes, we can create a mapping between decls being imported and original decls as an alternative solution. However, I cannot find any counterexample.
lib/AST/ASTStructuralEquivalence.cpp | ||
---|---|---|
1037 | Is it worth it to assert if only one Decl should be in isBeingDefined() state at time? | |
unittests/AST/ASTImporterTest.cpp | ||
3729 | Looks like this test is from another patch (D53693)? |
I wonder if it is possible to get into situation where non-equivalent decls are marked equivalent with this patch? If yes, we can create a mapping between decls being imported and original decls as an alternative solution. However, I cannot find any counterexample.
I don't think so.
This change is the natural extension what we already do (in line 1021 and 1022) with getDefinition().
getDefinition() works just as we would expect with a simple RecordDecl: getDefinition() returns a non-nullptr if isBeingDefined() is true.
However, getDefinition() may return a non-nullptr if D is a CXXRecordDecl even if D is being defined.
CXXRecordDecl *getDefinition() const { // We only need an update if we don't already know which // declaration is the definition. auto *DD = DefinitionData ? DefinitionData : dataPtr(); return DD ? DD->Definition : nullptr; }
This all depends on whether DefinitionData is set. And we do set that during ImportDefinition(RecordDecl *,).
And then we start importing methods and fields of the CXXRecordDecl via ImportDeclContext before the call to completeDefinition() which sets IsBeingDefined.
During those imports, the getDefinition() of a CXXRecordDecl will return with a non-nullptr value and we would go on checking the fields, but we are in the middle of importing the fields (or methods).
lib/AST/ASTStructuralEquivalence.cpp | ||
---|---|---|
1037 | Strictly speaking D1 will always come from the "From" context and such it should report true for isBeingDefined. But the structural equivalence logic should be independent from the import logic ideally, so I would not add that assert. | |
unittests/AST/ASTImporterTest.cpp | ||
3729 | Yes, exactly, good catch, I just removed it. |
I reverted this commit since it caused a regression in the lldb test suite, specifically TestDataFormatterLibcxxVector.py.
See the logs here http://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/12003/
Please monitor the lldb built bots when modifying ASTImporter.
Shafik,
Sorry for the inconvenience.
Seems like the libcxx tests of lldb are automatically skipped on Linux, so it slipped through my test execution.
Also, I did not receive any email from this build server about the build failure. Nevertheless, I'll monitor the buildbots with any next ASTImporter commit.
I think the fix for the assertion is easy to have, but it seems very difficult to test without having libcxx/MacOs at hand. Is there a way to execute libcxx tests from Linux?
@martong Hello, if I look at the specific test that was failing TestDataFormatterLibcxxVector.py it only has the following decorator @add_test_categories(["libc++"]) so that should not prevent it from running on Linux if you are also building libc++. If you do a local cmake build and you build libc++ as well does it still skip the test?
I could run the libcxx tests on my Linux machine (Ubuntu 16.04) by installing libcxx: sudo apt-get install libc++-dev.
From the logs of your build server seems like the crash happened with a _gmodules test.
Unfortunately, the gmodules tests are still skipped on Linux:
Collected 8 tests 1: test_ref_and_ptr_dsym (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... skipped 'test case does not fall in any category of interest for this run' 2: test_ref_and_ptr_dwarf (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... ok 3: test_ref_and_ptr_dwo (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... ok 4: test_ref_and_ptr_gmodules (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... skipped 'test case does not fall in any category of interest for this run' 5: test_with_run_command_dsym (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... skipped 'test case does not fall in any category of interest for this run' 6: test_with_run_command_dwarf (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... ok 7: test_with_run_command_dwo (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... ok 8: test_with_run_command_gmodules (TestDataFormatterLibcxxVector.LibcxxVectorDataFormatterTestCase) Test that that file and class static variables display correctly. ... skipped 'test case does not fall in any category of interest for this run' ---------------------------------------------------------------------- Ran 8 tests in 1.260s
This is aligned with the content of test_categories.py:
def is_supported_on_platform(category, platform, compiler_path): if category == "dwo": # -gsplit-dwarf is not implemented by clang on Windows. return platform in ["linux", "freebsd"] elif category == "dsym": return platform in ["darwin", "macosx", "ios", "watchos", "tvos", "bridgeos"] elif category == "gmodules": # First, check to see if the platform can even support gmodules. if platform not in ["freebsd", "darwin", "macosx", "ios", "watchos", "tvos", "bridgeos"]: return False return gmodules.is_compiler_clang_with_gmodules(compiler_path) return True
So apparently I cannot run gmodules tests on Linux.
My next step is trying to reproduce the issue on a real MacOS laptop.
I have reproduced the issue on MacOS, fixed it and updated the patch accordingly.
Soon I will commit and will monitor if any build bots are being broken.
Is it worth it to assert if only one Decl should be in isBeingDefined() state at time?