Skip to content

[libclang/C++] Fix clang_File_isEqual for in-memory files #135773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 23, 2025

Conversation

DeinAlptraum
Copy link
Contributor

@DeinAlptraum DeinAlptraum commented Apr 15, 2025

Add tests for clang_File_isEqual (on-disk and in-memory)

Add tests for clang_File_isEqual (on-disk and in-memory)
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Apr 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 15, 2025

@llvm/pr-subscribers-clang

Author: Jannick Kremer (DeinAlptraum)

Changes

Add tests for clang_File_isEqual (on-disk and in-memory)


Full diff: https://github.com/llvm/llvm-project/pull/135773.diff

1 Files Affected:

  • (modified) clang/unittests/libclang/LibclangTest.cpp (+49)
diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index 6de4d02bf74f4..b2a87d240e56e 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -1410,3 +1410,52 @@ TEST_F(LibclangRewriteTest, RewriteRemove) {
   ASSERT_EQ(clang_CXRewriter_overwriteChangedFiles(Rew), 0);
   EXPECT_EQ(getFileContent(Filename), "int () { return 0; }");
 }
+
+TEST_F(LibclangParseTest, FileEqual) {
+  std::string AInc = "a.inc", BInc = "b.inc", Main = "main.cpp";
+  WriteFile(Main, "int a[] = {\n"
+                  "    #include \"a.inc\"\n"
+                  "};\n"
+                  "int b[] = {\n"
+                  "    #include \"b.inc\"\n"
+                  "};");
+  WriteFile(AInc, "1,2,3");
+  WriteFile(BInc, "1,2,3");
+
+  ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr,
+                                       0, TUFlags);
+
+  CXFile AFile = clang_getFile(ClangTU, AInc.c_str()),
+         AFile2 = clang_getFile(ClangTU, AInc.c_str()),
+         BFile = clang_getFile(ClangTU, BInc.c_str()),
+         MainFile = clang_getFile(ClangTU, Main.c_str());
+
+  ASSERT_FALSE(clang_File_isEqual(MainFile, AFile));
+  ASSERT_FALSE(clang_File_isEqual(AFile, BFile));
+  ASSERT_TRUE(clang_File_isEqual(AFile, AFile2));
+}
+
+TEST_F(LibclangParseTest, FileEqualInMemory) {
+  std::string AInc = "a.inc", BInc = "b.inc", Main = "main.cpp";
+  MapUnsavedFile(Main, "int a[] = {\n"
+                       "    #include \"a.inc\"\n"
+                       "};\n"
+                       "int b[] = {\n"
+                       "    #include \"b.inc\"\n"
+                       "};");
+  MapUnsavedFile(AInc, "1,2,3");
+  MapUnsavedFile(BInc, "1,2,3");
+
+  ClangTU = clang_parseTranslationUnit(Index, UnsavedFiles[0].Filename, nullptr,
+                                       0, &UnsavedFiles.front(),
+                                       UnsavedFiles.size(), TUFlags);
+
+  CXFile AFile = clang_getFile(ClangTU, UnsavedFiles[1].Filename),
+         AFile2 = clang_getFile(ClangTU, UnsavedFiles[1].Filename),
+         BFile = clang_getFile(ClangTU, UnsavedFiles[2].Filename),
+         MainFile = clang_getFile(ClangTU, UnsavedFiles[0].Filename);
+
+  ASSERT_FALSE(clang_File_isEqual(MainFile, AFile));
+  ASSERT_FALSE(clang_File_isEqual(AFile, BFile));
+  ASSERT_TRUE(clang_File_isEqual(AFile, AFile2));
+}

@DeinAlptraum
Copy link
Contributor Author

@AaronBallman this is the fix PR for the bug we discussed at #130383 (comment)

The first test is for completeness' sake, the second one (with in-memory files) fails without the fix

@DeinAlptraum
Copy link
Contributor Author

Also cc @Endilll

Copy link
Contributor

@Endilll Endilll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but how this fares against our stability guarantees for libclang APIs? Do we need clang_File_isEqual2?

@DeinAlptraum
Copy link
Contributor Author

DeinAlptraum commented Apr 18, 2025

Have we documented exact requirements for this anywhere?
I'm not sure what the point of stability would be here: clang_File_isEqual returns True for all comparisons of in-memory files, which just makes this useless in practice. Any code that relies on this would be wrong to begin with...

@DeinAlptraum
Copy link
Contributor Author

@AaronBallman ping/reminder for a review 🙇

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for the fix!

@AaronBallman
Copy link
Collaborator

LGTM, but how this fares against our stability guarantees for libclang APIs? Do we need clang_File_isEqual2?

I think this is a bug fix and so it meets our requirements. The ABI is stable, but we can fix logic bugs.

@DeinAlptraum DeinAlptraum merged commit d7215c0 into llvm:main Apr 23, 2025
14 of 15 checks passed
@DeinAlptraum DeinAlptraum deleted the cpplibclang-fileequality-bugfix branch April 23, 2025 16:41
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add tests for `clang_File_isEqual` (on-disk and in-memory)
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add tests for `clang_File_isEqual` (on-disk and in-memory)
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add tests for `clang_File_isEqual` (on-disk and in-memory)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:as-a-library libclang and C++ API clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants