Skip to content
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

[clang] fix merging of UsingShadowDecl #80245

Merged
merged 1 commit into from
May 30, 2024

Conversation

mizvekov
Copy link
Contributor

@mizvekov mizvekov commented Feb 1, 2024

[clang] fix merging of UsingShadowDecl

Previously, when deciding if two UsingShadowDecls where mergeable,
we would incorrectly only look for both pointing to the exact redecla
ration, whereas the correct thing is to look for declarations to the
same entity.

This problem has existed as far back as 2013, introduced in commit fd8634a.

This problem could manifest itself as ODR check false positives when importing modules.

Fixes: #80252

@mizvekov mizvekov self-assigned this Feb 1, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules labels Feb 1, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 1, 2024

@llvm/pr-subscribers-clang-modules

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

Changes

[clang] fix merging of UsingShadowDecl

Previously, when deciding if two UsingShadowDecls where mergeable,
we would incorrectly only look for both pointing to the exact redecla
ration, whereas the correct thing is to look for declarations to the
same entity.

This problem has existed as far back as 2013, introduced in commit fd8634a.

This problem could manifest itself as ODR check false positives when importing modules.

Fixes: #ISSUE_TO_BE_CREATED


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

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+3)
  • (modified) clang/lib/AST/ASTContext.cpp (+1-1)
  • (added) clang/test/Modules/cxx20-decls.cppm (+42)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b7b11ab3a6b2e..aa14b8e931101 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -181,6 +181,9 @@ Bug Fixes to C++ Support
   and (`#79745 <https://github.com/llvm/llvm-project/issues/79745>`_)
 - Fix incorrect code generation caused by the object argument of ``static operator()`` and ``static operator[]`` calls not being evaluated.
   Fixes (`#67976 <https://github.com/llvm/llvm-project/issues/67976>`_)
+- Fix incorrect merging of modules which contain using declarations which shadow
+  other declarations. This could manifest as ODR checker false positives.
+  Fixes (`#TODO <https://github.com/llvm/llvm-project/issues/TODO>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 71c9c0003d18c..feeb350bf3e0c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6732,7 +6732,7 @@ bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const {
   // Using shadow declarations with the same target match.
   if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) {
     const auto *USY = cast<UsingShadowDecl>(Y);
-    return USX->getTargetDecl() == USY->getTargetDecl();
+    return declaresSameEntity(USX->getTargetDecl(), USY->getTargetDecl());
   }
 
   // Using declarations with the same qualifier match. (We already know that
diff --git a/clang/test/Modules/cxx20-decls.cppm b/clang/test/Modules/cxx20-decls.cppm
new file mode 100644
index 0000000000000..ee9f117278884
--- /dev/null
+++ b/clang/test/Modules/cxx20-decls.cppm
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+//
+// RUN: %clang_cc1 -std=c++20 -I %t %t/A.cppm -emit-module-interface -o %t/A.pcm -verify
+// RUN: %clang_cc1 -std=c++20 -I %t %t/B.cpp -fmodule-file=A=%t/A.pcm -fsyntax-only -verify -ast-dump-all -ast-dump-filter baz | FileCheck %s
+
+//--- foo.h
+namespace baz {
+  using foo = char;
+  using baz::foo;
+}
+
+//--- A.cppm
+// expected-no-diagnostics
+module;
+#include "foo.h"
+export module A;
+
+//--- B.cpp
+// expected-no-diagnostics
+#include "foo.h"
+import A;
+// Since modules are loaded lazily, force loading by performing a lookup.
+using xxx = baz::foo;
+
+// CHECK-LABEL: Dumping baz:
+// CHECK-NEXT: NamespaceDecl 0x[[BAZ_REDECL_ADDR:[^ ]*]] prev 0x[[BAZ_ADDR:[^ ]*]] <{{.*}}> line:{{.*}} imported in A.<global> hidden <undeserialized declarations> baz
+// CHECK-NEXT: |-original Namespace 0x[[BAZ_ADDR]] 'baz'
+// CHECK-NEXT: |-TypeAliasDecl 0x[[ALIAS_REDECL_ADDR:[^ ]*]] prev 0x[[ALIAS_ADDR:[^ ]*]] <{{.*}}> col:{{.*}} imported in A.<global> hidden foo 'char'
+// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'char'
+// CHECK-NEXT: |-UsingDecl 0x{{[^ ]*}} first 0x[[USING_ADDR:[^ ]*]] <{{.*}}> col:{{.*}} imported in A.<global> hidden baz::foo
+// CHECK-NEXT: | `-NestedNameSpecifier Namespace 0x[[BAZ_REDECL_ADDR]] 'baz'
+// CHECK-NEXT: `-UsingShadowDecl 0x{{[^ ]*}} prev 0x[[SHADOW_ADDR:[^ ]*]] <{{.*}}> col:{{.*}} imported in A.<global> hidden implicit TypeAlias 0x[[ALIAS_REDECL_ADDR]] 'foo'
+
+// CHECK-LABEL: Dumping baz:
+// CHECK-NEXT: NamespaceDecl 0x[[BAZ_ADDR]] <{{.*}}> line:{{.*}} baz
+// CHECK-NEXT: |-TypeAliasDecl 0x[[ALIAS_ADDR]] <{{.*}}> col:{{.*}} referenced foo 'char'
+// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'char'
+// CHECK-NEXT: |-UsingDecl 0x[[USING_ADDR]] <{{.*}}> col:{{.*}} baz::foo
+// CHECK-NEXT: | `-NestedNameSpecifier Namespace 0x[[BAZ_ADDR]] 'baz'
+// CHECK-NEXT:  `-UsingShadowDecl 0x[[SHADOW_ADDR]] <{{.*}}> col:{{.*}} implicit TypeAlias 0x[[ALIAS_ADDR]] 'foo'

@ChuanqiXu9 ChuanqiXu9 changed the title Users/mizvekov/bug/clang merge usingshadowdecl [clang] fix merging of UsingShadowDecl Feb 1, 2024
@ChuanqiXu9
Copy link
Member

Before looking into it, I remember the user branch is only allowed for stacked review. If this patch is not the case, let's try to create a new PR.

@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 1, 2024

Hmm I have been doing user branches for a while, this saves me time in case I want to split the patch off in a separate MR.
It's already the case that this is split into test adding + fixing commits.

In any case, the user branch will be deleted as soon as this is merged.

Can we go ahead, and clarify the rules for the next time, since this is such a small patch and windows CI takes 3 hours?

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

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

IIRC, in #79959, you're saying the patch have the potential to fix #78850? Is it true?

clang/test/Modules/cxx20-decls.cppm Outdated Show resolved Hide resolved
clang/docs/ReleaseNotes.rst Outdated Show resolved Hide resolved
@mizvekov mizvekov force-pushed the users/mizvekov/bug/clang-merge-usingshadowdecl branch from b44f1b2 to 895c615 Compare February 1, 2024 07:23
@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 1, 2024

The issue is up: #80252

@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 1, 2024

IIRC, in #79959, you're saying the patch have the potential to fix #78850? Is it true?

Yeah, looking at the similarities, there is a decent chance this is the same issue, it's worth trying it out.

@ChuanqiXu9
Copy link
Member

The issue is up: #80252

Thanks. Although I feel it is too implementor's view, (I mean the end users can hardly understand it), it is much better.

Yeah, looking at the similarities, there is a decent chance this is the same issue, it's worth trying it out.

Yeah, let's give it a try.

@mizvekov mizvekov force-pushed the users/mizvekov/bug/clang-merge-usingshadowdecl branch from 895c615 to f2e37f0 Compare February 1, 2024 19:18
@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 1, 2024

I have rebased on top of the change which reenables GMF ODR checker on the test suite, so I added a new regression test that exercises the false positive ODR violation.

@ChuanqiXu9
Copy link
Member

But the test for dumpped text still looks not good. Can we get rid of that?

@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 2, 2024

I took a look at what sort of complexity unittest would entail here. I don't think it's a good compromise complexity wise, it's a lot of boilerplate just to test a few AST nodes are correctly linked.

On the other hand, these AST tests don't look particularly out of place compared to a lot of other AST tests we have.

However, I have seen that there are a lot of other related merging issues, so I will leave the tangentially related tests for another MR.

@ChuanqiXu9
Copy link
Member

I took a look at what sort of complexity unittest would entail here. I don't think it's a good compromise complexity wise, it's a lot of boilerplate just to test a few AST nodes are correctly linked.

But they are much easier to maintain than dumpped AST text. I feel things get pretty clear with unittests. And I don't think there are a lot of complexities. They indeed have some boilerplates. But I think it is worhty to make things get tested. Also the boilerplates can be improved by refactoring and it is not so hurting since they are tests.

On the other hand, these AST tests don't look particularly out of place compared to a lot of other AST tests we have.

But that is not good. We should try to avoid that.

However, I have seen that there are a lot of other related merging issues, so I will leave the tangentially related tests for another MR.

I am not sure what's your meaning. What's your intention of testing of this patch itself? And I think it is not maintainable or acceptable to test the dumpped text in the following patches.

@mizvekov mizvekov force-pushed the users/mizvekov/bug/clang-merge-usingshadowdecl branch from f2e37f0 to 1e68272 Compare February 2, 2024 03:48
@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 2, 2024

I just pushed the change on this patch. What I meant is this patch will get, besides aforementioned regression test involving ODR checker failure, a simpler AST test that verifies just the UsingShadowDecl is correctly merged.

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

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

I still think the testing for dumped text is not acceptable. Let's make it prettier in unittest.

clang/test/Modules/GH80252.cppm Outdated Show resolved Hide resolved
clang/test/Modules/GH80252.cppm Outdated Show resolved Hide resolved
clang/test/Modules/cxx20-decls.cppm Outdated Show resolved Hide resolved
@mizvekov
Copy link
Contributor Author

mizvekov commented Feb 2, 2024

There is a lot of activity going on just in clang/test/AST, with multiple commits a day.
I think there is a time and place, and the right tradeoffs for all kinds of tests we have. Shall we get others opinions?
Shall we make an RFC so we get the community aligned on this new direction?

@mizvekov mizvekov force-pushed the users/mizvekov/bug/clang-merge-usingshadowdecl branch from 1e68272 to db966f6 Compare February 2, 2024 05:30
@ChuanqiXu9
Copy link
Member

There is a lot of activity going on just in clang/test/AST, with multiple commits a day. I think there is a time and place, and the right tradeoffs for all kinds of tests we have. Shall we get others opinions? Shall we make an RFC so we get the community aligned on this new direction?

Sounds not bad. I just sent https://discourse.llvm.org/t/rfc-prefer-unittests-over-matching-dumpped-ast/76729

clang/test/Modules/cxx20-decls.cppm Outdated Show resolved Hide resolved
clang/test/Modules/cxx20-decls.cppm Outdated Show resolved Hide resolved
Previously, when deciding if two UsingShadowDecls where mergeable,
we would incorrectly only look for both pointing to the exact redecla
ration, whereas the correct thing is to look for declarations to the
same entity.

This problem has existed as far back as 2013, introduced in commit
fd8634a.

This problem could manifest itself as ODR check false positives
when importing modules.

Fixes: #80252
@mizvekov mizvekov force-pushed the users/mizvekov/bug/clang-merge-usingshadowdecl branch from db966f6 to 9763cc9 Compare May 30, 2024 06:01
@mizvekov
Copy link
Contributor Author

I have revived this PR after a long time.

The original ODR violation bad diagnostic from the GH issue is gone from main, so I have removed the test for it.
My best guess is that the ODR checking must have gotten weakened somehow.
I really don't have time to dig into it though.

The original bug is still there in main, is self evident from looking at the source code, and can be confirmed bad and that it gets fixed by just looking at the AST dump.

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

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

LG. It looks not wise to block this good PR. After all, it is a change of 6 lines. Let's go ahead.

@mizvekov mizvekov merged commit 1ac592c into main May 30, 2024
8 checks passed
@mizvekov mizvekov deleted the users/mizvekov/bug/clang-merge-usingshadowdecl branch May 30, 2024 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang] incorrect merging of UsingShadowDecl
3 participants