[clang] [clang] Fix crash after merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource created 
https://github.com/llvm/llvm-project/pull/114240

Clang already has a mechanism to cleanup enumerators for typedefs to anonymous 
enums. So the following example code used to be handled correctly while 
merging, and ASTWriter behaves as expected:

```c
typedef enum { Val } AnonEnum;
```
However, the mentioned mechanism didn't handle named enums. This lead to stale 
declarations in `IdResolver`, causing an assertion violation in ASTWriter 
`Assertion `DeclIDs.contains(D) && "Declaration not emitted!"' failed.` when a 
module is being serialized with the following merged enums:

```c
typedef enum Enum1 { Val_A } Enum1;
enum Enum2 { Val_B };
```

The PR applies the same mechanism in the named enums case. Additionally, I 
dropped the call to `getLexicalDeclContext()->removeDecl` as it was causing a 
wrong odr-violation diagnostic with anonymous enums.

Might be easier to to review commit by commit. Any feedback is appreciated.

### Context

This fixes frontend crashes that were encountered when certain Objective-C 
modules are included on Xcode 16. For example, by running `CC=/path/to/clang-19 
xcodebuild clean build` on a project that contains the following Objective-C 
file:

```c
#include 

int main() {
  return memory_order_relaxed;
}
```
This crashes the parser in release, when ASTReader tried to load the enumerator 
declaration.

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/4] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c81..70bbb882eb2b13 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d6..54c4c5f4e5395e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/4] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletion

[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Clean up enumerators when merging named enums (PR #114240)

2024-10-30 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-10-31 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-10-31 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-10-31 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-11-06 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Ping?

Note that this PR fixes a crash in ASTWriter on valid Objective-C modules code; 
The initial PR title didn't accurately reflect that.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-06 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Gentle ping, and I wish you all a happy new year. :smile: 

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-05 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

Thank you all for looking into this :pray:

> Can we solve this issue by reusing some level of modules-specific declaration 
> shadowing?

I am new to modules, and I only learned how this part of the code works while 
debugging the crash I am sharing here. I am not entirely sure I understand what 
this means, could you provide some pointers that I can start from (e.g. 
function names, commits, ...etc)?

I can try to dig into this at the end of this week or next week if needed...

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-05 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-05 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-05 Thread Michael Jabbour via cfe-commits


@@ -2639,6 +2628,19 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::CleanupMergedEnum(Scope *S, Decl *New) {

michael-jabbour-sonarsource wrote:

> Is MergeTypedefNameDecl not called for the motivating example?

Unfortunately, it seems to me that `MergeTypedefNameDecl` is only called in the 
typedef to anonymous enum case (`MyEnum3` in the test case I am adding). For 
the rest of the enum cases, the closest I found was 
`Sema::ActOnDuplicateDefinition`, which is called when merging all tags (and 
this is where I am adding the new call to `CleanupMergedEnum`).

> Can we find a common path when merging definitions to put that logic there?

I could only see that merging enums for C and Obj-C crashes in this case (C++ 
works differently, see 
[here](https://github.com/llvm/llvm-project/pull/114240#issuecomment-2614544626)),
 and I found `Sema::ActOnDuplicateDefinition` during my investigation to be the 
function that handles merging tags.

I am not aware of a central place for merging definitions in general. Could you 
provide some hints on what to look for?

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-12-16 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Thanks for the update @vsapsai. Sounds good. Let me know if there are any 
changes that can make reviewing the PR easier!

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-11-17 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Gentle ping :smile:

The aim of the PR is to fix an ASTWriter crash that currently happens when 
serializing merged enums. Such a case was encountered while parsing Objective-C 
code that uses the XCode 16 SDK. If any of the changes look risky, I am happy 
to rework them and/or add more tests to increase confidence.

Thanks in advance.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2024-12-03 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Gentle ping :smile:

I would love to hear your feedback, and if any changes are needed, I am happy 
to address them promptly.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/6] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c81..70bbb882eb2b13 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d6..54c4c5f4e5395e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/6] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b13..d53bcf63dd1bd9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487aef..750301a9155d79 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetT

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

@vsapsai Thank you very much for the input. :pray: 

> Can you trigger the crash without -ast-dump-all?

> Can you use in the test %clang_cc1 instead of %clang?

I addressed both of these in f6f0887d22172c9db4f602b7f272630a97a708bd. I added 
a separate invocation without `-ast-dump-all` that reproduces the crash prior 
to this PR. I also switched to `%clang_cc1` instead of `%clang`.

For convenience, you can also find the crashing example here on CE: 
[link](https://godbolt.org/#z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIAkoBMg74IPatMjGAPLayCbhAGIW6LYkROgo6EFYAGax9LDorjjBqG4gXumxhSollvGJILQIJBiuAHQIWKAM%2Bji0orYE5tquOYwADB20HCQ4tgDKhtqoBEkMAIyjISZxw/rmdsCF7QCUWBA5eYYF7uUZloUALBVxCUnoAB4JJpaNBCYmrYyj3b1%2BoMGCNcGMJtNZvNFqDOmsNiCtjs9gxDsdcvlCkt7oUAGz3KpJIiGVzaD7E1ykH5tf49PoDdyIsHjSYzOYLRgrMHw2ybLDbeyFTw%2BPxok6Y9x3K4udwAdgJjxAHBJlBiliWzV%2B7TBAPpwNh4NZUI5y1W615TIFu3cwt8PjFGLOhQArDj3AAOBXVZWuVWxLyamk6ulAxkGlmQ9mLLlw818q1Cvyio7ip3ufHSwoATi9SR9gjV6EDf2DgIZfM6EbZ0M5ZoRoITNqT9sOnU45HQ8lQhgAVugCMha1geyBsbZ0AB3QtYoaHcyMZ36C2gwyMaQYdAAam8Ki5g8RaKQRgGvEdqFw%2BGlhJqxqLCG%2B6UMtmQUwIJEso6lT%2BQwloneefIjsUVoeM2/gmHY6AAHKKrU9Q5Jqf6WAOOBPvgcSuGwhh9EQvLYhh4iTNB2hEJoVggK6JiGLQeSobYWE4XhWBUTRyB0YR45QSRZGoBRWBIf2bFPlMyD1MgDEkUxAkocJomoMgHHEaR5GukEYkSbho78XJClEVxym8c6hy0LejAAPRmZu0gIFu47PMgm7IBOhibi8byWLQjmoDgwDOKgnnIDZm4EKgJC1JuGTPDkm6TI5CCdJu8gAEpKEMlDIAAnusAxpK5tgkZuHAZbw%2BVEEs26yoIhUZQAau%2B/CUBVLDVSVJFLKovhpXEBVFa1RBeBVVVFXV5hCE1HWpelWU5OguXdUQg3VSN/BsE1LWlSoE1daVi3DfVzVKLKLBbZQqL8guS58qucENJq%2B4jIeHgkugp6nOeeAQFeiqkJMnwPmk36vu%2BSRLF%2Bz6/v%2BgEgOUIG2n4zGQTB1RuaYHxfD80lCbyxy2Jh2GSVpBF6dx5F3CxtFPhpTHk1jin6TxIB3JjdEiep%2BOadizOyWJdMk7xTM6VTWlqfJvMGYzxmmQwO6TGWW7eF4%2BaFs0CuTZNkwOT9tgQPsi0YMgcy2Et9WrX4xujcdKhVYdx1pWd84MIuWDLvoq4o%2B8Rbo1g91nRAR7Pa9%2BQXp9sTXqaj7PkDH6gxHP5/vIAFMiO2Kw2BCOcd9JJkkWFJUvx6DIVj6G40L%2BG42LDNLPiNN0aXzHURTtgV%2BRVf54XLOC%2BzUkF4JHc88T4utyL4ld8LOnN7xVeS1GjAUtnhUqoNk2bpuc%2BWAvvqFuVh2dY1K%2BbjZJADKg25eIrKpbyrZ/L/vLxUfJm4AFQ3zbN9r1uPp%2BpYA07zfK%2BH8fU%2B59N7%2Bivl4P%2Brlnj3wcs/NKK9X5pQQZQSa78N7W0qjfABVggFK1iGAm%2Bd8zgwLVkdSa9sLrOyuiAd%2BjRc4kB%2BD7R6x4XpnmDl9ao4cAaRzfNHMGcdIZJ0ZvyHYoERQ%2BHTtBRUn9L4tC5tjDCdciacT5kUeurFa6j2xDXJ8E9VFyNZvJOu%2Bjx4DwZsUYeRiTHKPFl4aeNZpZeBULLPUQCboIQQKrO2c4KEuywKuaRsQNQtEYUcf2J5WEfXYdGfQXCXw8JBnwiGCcoaulTmI8CiMpEX1AbInuMl5El00VgJRSkzFqMbnXbRTdTHkXMXkrGBiR6MWFvUvuosam8XMZ3ZpnMrGlNqXYk0FlNy8FMJlCKsQyHeMdpdJk/jsnfzupsJhAcImXlDoqThgN4mfljkkxOoIRz4jSXaDJGdvQkgLHg3J7c0I4zxj04p5cOl8SqZUhutMXmqVadzQxRTjH92sQzVS3SCa9MBf0wygzFjDNwevAY5pXCeSfBvL%2B6AAwIE3E%2BcwGVGhq0cc4oEOCFnovwWlYZup%2BiTGAJuNxTRMU2QwMFEggQUibimOgUgjkXKJBoFuQKW5KBTGkJuWwz1PJpG7AtOlzRNwTjyJigVB8cCuAGEbJ8bLJXGFRXixBBKQwDFcXUW6Hjr5ePOjMyhcylSXOVsE5ZhwsG8R1lgMgFEhgWpuPoIgo4hget8aubU9BsQhLgLAGAiAnqmFiO9fARho2WF4r0HY/Awp/nknRWg/A0DaFsGQCoyArD0AgJoPkmhJj1AykOct8RUAZRCJoPsA4hzxsSM%2BEItgcV8gGDoYAbB3zmHoOHAYpB7AfiZLkDAKEABuKQ%2BQvH7OEaJuBnwF3jDgTQoU61YQGHyNAOAfXh1nagTQ1F0AaFHcAcw1LlnpG2HQGqOBJw8iHLEqOCS9nxwOfoZOwj7CiNOfyDdWQXWGBMFjIdTBnhYsbb3WdTACCbiYGkd%2BnlkPvyYFSZDky1A0LoSYJDaRaAZWfCQZ4TBsUZVdse7yAwQPGR%2BQUh5YKnmuF0Voj5GjHlVPY23XuvymksYBe0oFLdtJs0ecPdjhw0CYFHNMp2AbGCbmeO6XETBcQ3GClaTcEA01WAg15XNZBdYQHXJgU%2Bu59j6EYY69AR9yIuodl6rAPqVDukaI42UuJZRLFlGp507ohg3BUK6JTQaQAetDRGv2IBZgRHCMHeNZhE1I0WKp9TmntM7E3EsLMjQNSgjfTsmOsT9lQxDRuFVWkJyhRMLWBTsyVyMDCAlhyhhcoZY01p5N9hdP6YzU%2BAKqBjOmawgm7BO4ljWe9g6z13qQC4g1N5xxXh3ReCWCoG4eXnT4nC/oegUW5tuudB6h2KgmuuxLLZi1XhLt%2BOu3N49NE0I3CAA%3D%3D).

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

Thanks for raising the concern. I am also not entirely sure, but I chose to 
remove it for two reasons:

 1. It seems to me that the presence of this `removeDecl()` call causes an 
incorrect ODR violation diagnostic when `-ast-dump-all` is provided (which I am 
using in my regression test to expect the AST nodes after merging):

```
In module 'ModB' imported from :1:
In module 'ModA' imported from ./ModBFile.h:2:
./shared.h:6:9: error: 'MyEnum3' has different definitions in different 
modules; definition in module 
'ModA.ModAFile1' first difference is enum with 1 element
6 | typedef enum { MyVal_C } MyEnum3;
  | ^~~~
./shared.h:6:9: note: but in 'ModB' found enum with 0 elements
6 | typedef enum { MyVal_C } MyEnum3;
  | ^~~~
1 error generated.
```

This incorrect ODR violation can be observed before this patch. CE link: 
[here](https://godbolt.org/#z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIAkoBMg74IPatMjGAPLayCbhAGIW6LYkROgo6EFYAGax9LDorjjBqG4gXumxhSollvGJILQIJBiuAHQIWKAM%2Bji0orYE5tquOYwADB20HCQ4tgDKhtqoBEkMAIyjISZxw/rmdsCF7QCUWBA5eYYF7uUZloUALBVxCUnoAB4JJpaNBCYmrYyj3b1%2BoMGCNcGMJtNZvNFqDOmsNiCtjs9gxDsdcvlCkt7oUAGz3KpJIiGVzaD7E1ykH5tf49PoDdyIsHjSYzOYLRgrMHw2ybLDbeyFTw%2BPxok6Y9x3K4udwAdgJjxAHBJlBiliWzV%2B7TBAPpwNh4NZUI5y1W615TIFu3cwt8PjFGLOhQArDj3AAOBXVZWuVWxLyamk6ulAxkGlmQ9mLLlw818q1Cvyio7ip3ufHSwoATi9SR9gjV6EDf2DgIZfM6EbZ0M5ZoRoITNqT9sOnU45HQ8lQhgAVugCMha1geyBsbZ0AB3QtYoaHcyMZ36C2gwyMaQYdAAam8Ki5g8RaKQRgGvEdqFw%2BGlhJqxqLCG%2B6UMtmQUwIJEso6lT%2BQwloneefIjsUVoeM2/gmHY6AAHKKrU9Q5Jqf6WAOOBPvgcSuGwhh9EQvIqHcGHiJM0HaEQmhWCAromIYtB5KhthYTheF3NRtHIPRRHjlBpHkaglFYEh/bsU%2BUzIPUyCMaRzECegyHCdMYmoMgnEkWRFGukE4mSbhID4QJinKcR3FqXxzqHLQt6MAA9FZm7CD0xiJM%2BkzAJuyAIFu47PMgbkToYm4vG8li0G5qA4MAzioCF7lbgQqAkLUm4ZM8OSbpMbkIJ0m7yAASkoQyUDZbkAJ7rAMaQBbYpGbhwxW8FVRBLNusqCDVxUAGrvvwlDNSwbX1aRSyqL4BVFXE1W1QNRBeM1rW1Z15hCL1w35ZQq3IKVOToBV41ELNbULfwbC9f1DUqCtBWrbt%2B3zV1fVKLKLAXZQqL8guS58qucENJq%2B4jIeHgkugp6nOeeAQFeiqkJMnwPmk36vu%2BSRLF%2Bz6/v%2BgG6fyOygSKPhYBBXGKoFpgfF8PyCShaHHLYmHYVJo5YIRRk8RRLE0XRT7aby2KsZztgqcZvEgHclPyaJWn0zp2Ji/REtKYLrN8aLBnc4zmkKyzJki%2BZlkMDukxllu3hePmhbNCbq2rZMPnQ7YED7PtGDIHMtgHV1x1%2BO7i1PSorUPU9BWvfODCLlgy76KuJPvEW5NYH9r0QEeQMg/kF4Q7E16mo%2Bz6Ix%2BKM5z%2Bf7yABTIjtiIG2n4BOQTB1QUmSRYUlSMlyfR6G02r2LM1xSujvifPyV3BMc/Jiva0s%2BKyyJqtSzzrdCXLBnj8Lk/6ZLTHq8vWur7iutRowDeWDVKqzatm6bkfW4%2Bn66pnwVF8Xx5JADKg25eKbKqFhqCCWw/j8vGokpTcAAqc%2By1/5XxPr6QsM0HojR6o/Z%2Br936fxgf6C2H9wEX0AWcHyYD/4Byto9K2BUoH5nvog5BVhUFm1iJgrw4DcHAIIWtEhQc5zvXDp9EAV9GjNxID8BOANjzAzPOnSG1Rs7w1zm%2BfOqMi4YzLiLbG9hcZ2nArXRUN9v6IVkovamGFh491UsLYog96LDwsU%2BFeFFijTwUhvBmMt9FU0cZrXu2t7Gz03jLbenizH7xrPrLwKhDZ6lQd9BCv8sEcLeqHD6TJVw6NiD/eOmwREp3EeDSR0Z9AyJfHI5GCj0Yl0xq6SuYEa5E29F/DBLQHEdzpr4pmtNbF8XMaPSxc9GbWIFjvOxC83Hywkj0lxbcZ7iXaUUdeSlh4a0MgEuxQSTRFV4KYDaSVYirWDlwiOWBkl1MsAGFowijjJxPNky8mdFTSIRkUz8hdSml1BCOfElS8aaJqXmEkBZ6ENNcfJJpxi2kDNMiPNi3SWl9OmRpQFS8nHSyGeLfxpj1KzNGS0hZsKVmLCKnQ4%2BAxzSuBCk%2BaBt90AnM3E%2BcwxVGhW1CeEoEtCjmUoYatIqup%2BguU3FEpoCBNweQwJuN8gQUibimOgUgbl/KJBoFuGKm5KBTGkJuWwQMQppG7HtPlzRNwTjyAKxVmVXADDdk%2BcVWrjDkvpZdRlIYBiRLqD9GJjC4khzDvsw5rg/kfFORkw41C%2BIOywGQSiQx4k3H0EQUcQwI1epLPQbEZy4CwBgIgQGphYhg3wEYLNlg%2BK9B2PwBKf4lL0VoPwNA2hbBkAqMgKw9AICaD5JoSY9RipDjbfEVAxUQiaD7AOIceanLIBCLYWlfIBg6GAGwd85h6DZwGKQewH4mS5AwChAAbikPkLx%2BzhDybgZ8sl4w4E0PFXtWEBh8jQDgGN2cd2oE0DRdAGgV3AHMC5DJ6Rth0HajgScPIhwFLzsUp5xcXn6HLqo0AVd8Zfs0FkENhgTDyUXUwZ41KB2Lx3UwAgm4mBpCviFIjV8mBUiI9stQfCBEmEI2kWgxVnwkGeEwGlxVCMAA0i32EIwlZATBSSmCYPOyOT6woDGQ%2BZeFhjO5jNaa4aZvMulcwUzCsF6tZPuMxc45FCKPFor4n4xF89sWaaWIcNAmBRycISdwpJjBNzPHdLiJguIbgiqtJuCAparDodCjWsgjsIDrkwO/Xc%2Bx9DCMDegF%2BFEQ0hyjVgGNKh3SNFCbKXEsoliylc86d0QwbgqFdAm7U9AI0pvTUnEAswIjhHTnmswBa66LBc25jzXmdibiWFmRoGpQSgYeQXApzzMbJo3Dgdw2IJzxRMLWOznqeEMDCPVnyhgKrtfc553jrlfO0DLQF6ttaQtYXzTQnclnosBsjdGkAuINRZdCV4d0Xglj4V686fEZX9AVfSQeQ4YbnQRpDioRJK4SwxfiV4cHkdIc3afbRNCNwgA).

2. I am also not entirely sure if performing the call in the named enum case is 
safe. I can understand why it is important to remove the constant from 
IdResolver and the Enum context, but I don't know if removing the constant from 
the enum decl doesn't cause problems 

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits


@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);

michael-jabbour-sonarsource wrote:

Thanks for the suggestion, done in f55ca2bdf0e0fabdc672f0f85007d091272a8891.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

I can try to dig deeper to answer the points I mentioned (especially point 2) 
if desired, but I would need to allocate some time (maybe at the end of the 
week).

Any pointers/hints/thoughts would be appreciated.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

Additionally, as far as I can see, for `EnumDeclConstant`s created by the 
parser, the DeclContext is always the containing `Enum` itself:

https://github.com/llvm/llvm-project/blob/79231a86846b7dff09497fc58ea1e82e892052bd/clang/lib/Sema/SemaDecl.cpp#L19739-L19740

Therefore, after the refactoring I did, I think that the call can be simplified 
to:

```
ED->removeDecl(ECD);
```


https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-26 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/8] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c81..70bbb882eb2b13 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d6..54c4c5f4e5395e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/8] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b13..d53bcf63dd1bd9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487aef..750301a9155d79 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetT

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-26 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

@vsapsai Thanks again for the feedback :pray: 

> I've realized that the test doesn't have to be Objective-C, the failure is 
> reproducible in C. Curiously, we aren't hitting the assertion in 
> C++/Objective-C++ but I don't know why.

I dug a bit into this today, and I could find a few differences:

1. ODR checks seem to be implemented on C and ObjC only (see 
df0ee34bc2523f11b907311670c776cb3de108c1). As far as I understand, in the C++ 
case, `Sema::ActOnTag` sets [`SkipBody.ShouldSkip` to 
true](https://github.com/llvm/llvm-project/blob/cd708029e0b2869e80abe31ddb175f7c35361f90/clang/lib/Sema/SemaDecl.cpp#L17616),
 causing `ParseEnumSpecifier` to [skip the body and return 
early](https://github.com/llvm/llvm-project/blob/cd708029e0b2869e80abe31ddb175f7c35361f90/clang/lib/Parse/ParseDecl.cpp#L5553-L5561)
 before it would otherwise [call 
`ParseEnumBody`](https://github.com/llvm/llvm-project/blob/cd708029e0b2869e80abe31ddb175f7c35361f90/clang/lib/Parse/ParseDecl.cpp#L5603)
 and create the `EnumDeclConstant` AST node (that we need to clean up in the 
C/Objective-C case).

2. Another difference, which doesn't seem to contribute directly to the 
divergence in this specific case, is that in C++, `ASTReader` pre-loads a set 
of interesting identifiers, see 33e0f7ef94124a53404555879666cef0e370f8c2.

> I wanted to try defining the enums in different scopes (e.g. in a struct) and 
> see how it works. Consequences for scopes aren't clear, so that's worth 
> taking another look.

I added one more test case for this. I got the same stack trace, and the crash 
seems to be fixed after the PR as well. However, I couldn’t reproduce the stack 
trace with `WriteCUDAPragmas`, so I might be missing something. See the scoped 
example [on 
CE](https://godbolt.org/#z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIAkoBMg74IPatMjGAPLayCbhAGIW6LYkROgo6EFYAGax9LDorjjBqG4gXumxhSollvGJILQIJBiuAHQIWKAM%2Bji0orYE5tquOYwADB20HCQ4tgDKhtqoBEkMAIyjISZxw/rmdsCF7QCUWBA5eYYF7uUZloUALBVxCUnoAB4JJpaNBCYmrYyj3b1%2BoMGCNcGMJtNZvNFqDOmsNiCtjs9gxDsdcvlCkt7oUAGz3KpJIiGVzaD7E1ykH5tf49PoDdyIsHjSYzOYLRgrMHw2ybLDbeyFTw%2BPxok6Y9x3K4udwAdgJjxAHBJlBiliWzV%2B7TBAPpwNh4NZUI5y1W615TIFu3cwt8PjFGLOhQArDj3AAOBXVZWuVWxLyamk6ulAxkGlmQ9mLLlw818q1Cvyio7ip3ufHSwoATi9SR9gjV6EDf2DgIZfM6EbZ0M5ZoRoITNqT9sOnU45HQ8lQhgAVugCMha1geyBsbZ0AB3QtYoaHcyMZ36C2gwyMaQYdAAam8Ki5g8RaKQRgGvEdqFw%2BGlhJqxqLCG%2B6UMtmQUwIJEso6lT%2BQwloneefIjsUVoeM2/gmHY6AAHKKrU9Q5Jqf6WAOOBPvgcSuGwhh9EQvIqHcGHiJM0HaEQmhWEUWAmIYtB5KhthYTheF3NRtHIPRRHjlBpHkaglFIf27FPlMyD1MgjGkcxWACShwmiagyCcSRZEUcUQRiRJuEgPh0nyYpxHcSpfFeIctC3owQSoNoA6bhwACeIlWTZSiyr4QyUJum5xKRtl2bwtikc626ub5ABq778CwwVRTE6DmK4qhuZQLksIlqL8guS58qucENJq%2B4jIeHgkugp6nOeeAQFeiqkJMnwPmk36vu%2BSRLF%2Bz6/v%2BgHafyOygSKPhUZBMHVC8bwfF8PwyUJvLHLYmHYZJo5YIRBk8RRLE0XRT6aby2KsdtthKYZvEgHc030SJGmLVp2IXXJYnHetfHnXpu3LepClPUZZ2meZDA7pMZZbt4Xj5oWzSg0o7nQ5QkzIJutW2BA%2BzBYIm4YMgcy2GFEWpSo6MpbD6Xzgwi5YMu%2BirmNpgTQ%2BBXpRAR4lWV%2BQXlVsTXqaj7Ps1H5tTzP5/vIAFMiO2IgbafhDVxNUkmSRYUlS0lxYJ9HofN73YqtXHPaO%2BIHTNWtUVtM3fadSz4vd0xvTde0q8hM1XV9a0/ZbunXUxH16ebFGW39UaMBSCu2SqaOw55weWKHvqFks4fuZ5nkIOgJADKg25eGDKpx5DWcR0nLzUQpm4AFQF0TieI/L0c%2Bn6lheAnHlJynadWJn2ex/6edeAXnlF2cCPl1XlfJbKqUw%2B5UdbvmTfJ6n6cd%2BDsQ9wXA8l8PY8T5QJOZRT2UgNPjRKyQPwM0Vx6lWe7PVdU3ONbzb78%2B1QtdWLZ29fY/V2uBw2KnXucWjWw1gtL22t5q%2B2MibNi9FjaGw4q7U6alVayRtp7Jad0UFOx9og1SHsFLG0%2BvpXWP0TLSX%2BoDEMAwO65QQggKG7ld5kyykyVcADYgahaOfI4zMTzX0qrfaM%2BgH4vifq1F%2BnURbdVdJLMCMtoL/xzt3IBWD1ZzVARglaEDcFQPgTtO2y09FHR0fxVRD0CEGMwY7S6OCSFIPweJSxDjIFFADjWBgAB6Dxm5eCmGQHZTc0piZzj3pTLAbClEN3ypsC%2BLN%2BGXk5oqe%2BTUxGfkFpI0WoIRz4lkQNX%2BstvQkgLCvFR1i0LqONjrZSp1XRGLgabBBdiKKumts7RxYCHZq3McQ6pzSHGENsb0vizo3Emi8THYp0cBjmlcLQTcT4Y713QAGBA8zbDmDso0WGlDgZL0ics1e7lxm6n6JMYAm5aFNFWSnDAm43yBBSJuKY6BSCbmCIjKwzg3kp03JQKY0hNy2BKnMtI3YiAXLqHlVZE48irOQD8hAOBXADBxk%2BR5oLjCLK2TDLwKggZ6hoZCuhDCd4hOYfvVhSoikQy4TEw4rd074EOGQEAzohgZQYDcfQRBRxDHZWE1c2p6DYm4XAWAMBEDFVMLECq%2BAjDSssHxXoOx%2BAkFoH%2BBS9FaD8DQNoWwZAKjICsPQCAmg%2BSaEmPUOyQ4LXxFQHZEImg%2BwDiHPKxIz4QjrOtUyAYOhgBsHfOYeg3MBikHsB%2BH1OAMAoQAG4pD5C8fs4QhG4GfHFeMOBNCoCtVhAYfI0A4B5dzONqBNA0XQBoMNwBzBnJiekbYdBQo4EnDyIcIi%2BbiPScLTJ%2Bhxaf1AFLQaNbNBZBRuEkwM1g1MGeHczcTA0jTzmfO6eTAqTztiKoFgR8T4mDnWkWgdlnwkGeEwJ8GyqYltQEi%2BNkBTJmNmhhd6NxXRVJOhRcodSDHPugYdFx5RWm2y9t%2BgDj0TH/sA0tYDgy318RUIcNAmBRxkvJgKxgm5njulxEwXENw7lWk3BANVGrJ1vKsvq1GEB1yYEzrufY%2Bhz70oXhRMdpMuVYB5Sod0jRcWylxLKJYspMPOndEMG4KhXSoaFSAdloqJVMxALMCI4R2byrMIqkaiwMNYZw3hnYm4lhZkaBqUE7bUkCxERk7qIqNxIuWhObNJhazIZYSuRgYQlMI0MGkdDmHsO4eVfYAjRGrAkd1eRgjWEFXtx3EsOjWAGMcrYzy3EGpeO4q8O6LwSx8IGedPiST%2Bh6AybpVgFlbKOUqBc1TEsCXSZeCq%2BEmrJWS20TQjcIAA%3D).

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-27 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-26 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

I had a quick look into this today, and I could see that some other ODR checks 
aren't emitted unless `-ast-dump-all` is provided. For example, in [this CE 
example](https://godbolt.org/#z:OYLghAFBqd5TKALEAXATgU0wGgJYgQDGAtgIYDWmAgusAM4gDkAtACIDCAstQNICiAfQBCAVQCSAGTaCAKgE0ACvwCkAZjZtMAIwCuwJjiIB7EgAc8AG0zpJZAHbBdZYJnEATEERUAmYb%2BEjXXpUUwB5XVQzSIAxK0x7MhJMNEwQnAAzeMZYTHc8UPQPEB9M%2BOK1MutE5JB6JDIsdwA6JBxQJkM8enF7IktddzzmAAYu%2Bi4yPHsAZWNddCIUpgBGcbCzBNHDSwdgYs6AShwIPILjIs9KrOtigBYqhKSUzAAPJLNrZqIzM3bmca9fqDYZMMb4CZTWbzRbLcHdDZbME7PYHJjHU75QrFFaPYoANkeNRSJGM7l0X1J7nIfw6gL6AyGnmREMm0zmCyWzDWEMR9m2OF2jmK3j8AQxZ2xngeNzcngA7ETniAuGTqHFrCtWv9OhCgYzQfDIeyYVzVutNvyWUL9p5Rf4/BKsRdigBWPGeAAcStqqvc6viPm1dL1DJBzKNbOhnOWPIRloFNpFAXFJ0lLs8hNlxQAnD6Un7hBrMMGAaHgUyBd0oxzYdyLUjwUm7SnHcdutxKJhFOhjAArTBEVD1nB9kC4%2ByYADuxZxI2OlmYrsMVvBxmYsiwmAA1L41Dzh8iMSgTEN%2BM70PhCLLiSOMsZ7KgZkQyNZxzKH6hRPRu68BWP3RtLxW0CMwHEwAA5ZU/QDawgzaH9rCHPAH0IBJ3A4YwBhIflcXQyRpkg3QSG0GwShwMxjHoAoUPsTDsNwiiqJoh8CMnCDiNI9ByMQwdUFomZUEaVB6OIxjeOQh9BOEtiiJIsjShCYTRJw8ccCU9BUFkjj5O4nxjnoU1lgAemM7d%2BHMVAAE9t1lFQRmodFBSXFcBXXGDi3gnBDzGY8vDJTBz3OS8CAgG9lUMmNWl%2BTJP2fV8UhWD9H2/X9/3IoD7QCCjwKg2p6kaPJtQk/jUNOewMKwsS1PwwidK48jKOo0q6Kq1TcSalj7G0ziFPUzAkJa6TNJU8SBr4gShM0nrdJ4qaRLa8T5pmhr9PUozmASYjty4Kz%2BHsYifF3eVhB2qyADVXxEY62HUfwHKcxcmGXHBV0MdcCqabUfKciATwCoLCivML4lvchpm%2BGL70feK3yS2KUp/RQ/xZMdKkykCcvY5U3g%2BL4fj%2BEraLQirRpKUpavY3ruMqTqWrJnxSjp2iVrIyoiak%2BaGcU8bJNmZa6upkB2a5xbyfUgWqdmtQDI2pg92mCsd18HxC2LVoVfs6gtemVBt3B%2BwIEOY7TqwVAFnsbcODum6tcelzXrckBcfMfGYp%2BvzT0Ci9gfC2pzQRp8Xzh5KvyRlHwTHXEMbFPwscg5UqQpEsqRpfrBuJ8rKoYmqKtZ7iVkJZmHzJjrmJa/Px0JDn%2BeUsXcRr4atMF2bC4luuc4byW5IawvZZjZgk%2BsHa1RNrXt31slk5H/1ixWMeHIniekEwMghnQXdGY8%2BItSQTXF6Xt5KM07cACpx9tg%2Bh53be4IX6gl%2B3Fe15sTfVbVTyNcZi%2BJ6Pi49fPgfFQ8pboOWAaA7WDlr4z1OsA%2B6D8n6r3Xm/NW8Qv4%2BAvn/E%2BgDtYgLtguB2b0cDrmvs0VOZA/gexOP9M8PtQp%2B1jIYaGQcErvkDqlZG6UHgxwdKBXK0EP472KrzFqJNs7VTwnnFuDVabl1oqXJizUWbSLZunCanMO4SLUXzJulcRaaPau3aaKiab9zrPLBy1lNhDAyNuLaJATZWxuuZO6%2BDnLPVciydygjNTfW2IcY4z916EGOBQEAroRjuLuIYEg4TIlEPXLqRg7oqFwFgDQ72wVfag2VAHZhsNEqhw4RHQwY5CQ8OymBbGvoyRFjQQhERmd0IKMpj3MiRc5El3roorqldq6NI0SNbpjdu71XaUYhancJl9LMWaUyMDizbiGJadw9BtwPhnrBTA8F1n2EsFZZoWsFZhiGCgnx2z0FHLAZYqy1jMC2PsY4jgOBtxsGcaoNQ8D7YeMdl4lUtT1ZtA9oEpBZEjZRJiXE35a4yyMEicCnAYSInuLUJ4mFupUmIDScgfy5h4ghUICYPF1huL9D2IIMg9AfyaVovQQQGBdD2AoFUVANhGAQG0AKbQ0xGhWRHNyxI6ArJhG0AOIcI4iXJEfGEPZfKWRDD0MADgr5LCMADkMcgjg3zyrwFgZCAA3NIAo3iDkiIw/Aj4BqJjwNodAvLMJDAFBgPAsSA6GvQNoKimAtCauAJYaYHRfKZF2Awc6eBpx8jvHFYOhT2Hh3StHPYwFY6BH9doHI4LjBmBamqlgrxtxEG3CwDI181nFuviwGkxb4jqDYKQ8hZgi0ZHoFZR8ZBXgsAfPsotAANMljgi2UtQCwck5gWAqveu69AeAhgZoMgM/kWcWlSKlr3Hp9NunF26iYtSIyDFjQzoM5uq6yJd33bu0ZQsVjHAwNgccBCfkJOYNuV4np8QsHxHcAtNptwQEpdSnN24GVMuNhATc2BN77kOIYBFQSwUPuiTgWJrotTynxJ6NQOYVg%2BHxFhnMOZ8TyndE%2BpJIB4X%2BJOFilA8woiRGBkSiwJK8rLFfe%2Bz9369jbhWDmZoWpwT5JjWw5hxSE3eS3DOtSU47VmHrA%2Bl6JGIi0b1sYWxrGP1fv7cAX9/6bCAeAxQUDmFiWvz3NemD/iEOQruJ6ZoPh9z4hGJ6eUahHMjBGGoHwxGnakfI0eUJUKnqouhe9MsCKno%2BDRSFjFFmcDuuoqhO4QA),
 I have the enum `E` defined with different enumerators, and I don't get a 
diagnostic unless I have `-Xclang -ast-dump-all` on the command line (removing 
it, somehow removes the diagnostic).

While I still don't have a concrete answer for what I mentioned above, it seems 
to me that this is a separate bug in the ODR check implementation, and that 
ideally, we should get the diagnostic without the `-ast-dump-all`.

If my conclusion above is correct, I would argue that dropping this call is 
necessary for these ODR checks to work (once the bug above is fixed).

I may try to dig deeper later into why the diagnostics are not emitted without 
`-ast-dump-all`. I am curious about your thoughts here.

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-26 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-26 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

@vsapsai Thank you for sharing the previous patch. This is really interesting.

> For the record, the previous work I've abandoned is 
> https://reviews.llvm.org/D114833 Doesn't seem particularly relevant to this 
> change to be honest.

As far as I can see, it actually seems to introduce the exact same 
`IdResolver.RemoveDecl(ECD)` call in `Sema::ActOnDuplicateDefinition` that I am 
introducing in this PR, and this seems to be sufficient to fix the crash here 
as well.

I tried to understand why that work was abandoned, in order to know if the 
reasoning applies to the changes in my PR.

- Regarding the "ambiguous use of internal linkage declaration" warning in the 
C++ test ([this comment](https://reviews.llvm.org/D114833#3165889)), I could 
see that the currently the warning is emitted before and after my PR on that 
test, so I see no risk here.
- About handling anonymous enums ([this 
comment](https://reviews.llvm.org/D114833#3190487)), do you think any further 
action needs to be taken? I have a test case to show how their AST dump looks 
like...

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-01-21 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/7] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c81..70bbb882eb2b13 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d6..54c4c5f4e5395e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/7] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b13..d53bcf63dd1bd9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487aef..750301a9155d79 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetT

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-27 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/9] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c8..70bbb882eb2b1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d..54c4c5f4e5395 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/9] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b1..d53bcf63dd1bd 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487ae..750301a9155d7 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecE

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-03-07 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From 9eede4531ad27ce1d77df492076d5fbcd237fd3f Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Fri, 7 Mar 2025 09:32:54 +0100
Subject: [PATCH] [clang] Fix ASTWriter crash after merging named enums

---
 clang/docs/ReleaseNotes.rst |   1 +
 clang/include/clang/Sema/Sema.h |   8 +-
 clang/lib/Parse/ParseDecl.cpp   |   2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|   3 +-
 clang/lib/Sema/SemaDecl.cpp |  30 ---
 clang/test/Modules/modules-merge-enum.m | 111 
 6 files changed, 139 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 28856c27317f3..a25808e36bd51 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -248,6 +248,7 @@ Bug Fixes in This Version
 
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fixed a crash when merging named enumerations in modules (#GH114240).
 - Fixed rejects-valid problem when #embed appears in std::initializer_list or
   when it can affect template argument deduction (#GH122306).
 - Fix crash on code completion of function calls involving partial order of 
function templates
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 08621e633b55c..fdef57e84ee3d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4008,7 +4008,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
@@ -4132,6 +4132,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// CleanupMergedEnum - We have just merged the decl 'New' by making another
+  /// definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void CleanupMergedEnum(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 7ae136af47391..31cb4a24ad97e 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5652,7 +5652,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecError();
   return;
 }
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 43db715ac6d70..e48a35078892d 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2350,7 +2350,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind 
TagTokKind,
   // Parse the definition body.
   ParseStructUnionBody(StartLoc, TagType, cast(D));
   if (SkipBody.CheckSameAsPrevious &&
-  !Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
+  !Actions.ActOnDuplicateDefinition(getCurScope(),
+TagOrTempResult.get(), SkipBody)) {
 DS.SetTypeSpecError();
 return;
   }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 714210c3856d7..5716eb61d4ae8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2564,18 +2564,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  CleanupMergedEnum(S, NewTag);
 }
   }
 
@@ -2652,6 +2641,19 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
Typ

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-03-07 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From d5c710e5a16f77b5a44bb842d09674a8b40dbd0d Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Fri, 7 Mar 2025 09:32:54 +0100
Subject: [PATCH] [clang] Fix ASTWriter crash after merging named enums

---
 clang/docs/ReleaseNotes.rst |   1 +
 clang/include/clang/Sema/Sema.h |   8 +-
 clang/lib/Parse/ParseDecl.cpp   |   2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|   3 +-
 clang/lib/Sema/SemaDecl.cpp |  30 ---
 clang/test/Modules/modules-merge-enum.m | 111 
 6 files changed, 139 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 28856c27317f3..a25808e36bd51 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -248,6 +248,7 @@ Bug Fixes in This Version
 
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fixed a crash when merging named enumerations in modules (#GH114240).
 - Fixed rejects-valid problem when #embed appears in std::initializer_list or
   when it can affect template argument deduction (#GH122306).
 - Fix crash on code completion of function calls involving partial order of 
function templates
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 08621e633b55c..fdef57e84ee3d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4008,7 +4008,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
@@ -4132,6 +4132,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// CleanupMergedEnum - We have just merged the decl 'New' by making another
+  /// definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void CleanupMergedEnum(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 7ae136af47391..31cb4a24ad97e 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5652,7 +5652,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecError();
   return;
 }
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 43db715ac6d70..e48a35078892d 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2350,7 +2350,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind 
TagTokKind,
   // Parse the definition body.
   ParseStructUnionBody(StartLoc, TagType, cast(D));
   if (SkipBody.CheckSameAsPrevious &&
-  !Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
+  !Actions.ActOnDuplicateDefinition(getCurScope(),
+TagOrTempResult.get(), SkipBody)) {
 DS.SetTypeSpecError();
 return;
   }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 714210c3856d7..5716eb61d4ae8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2564,18 +2564,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  CleanupMergedEnum(S, NewTag);
 }
   }
 
@@ -2652,6 +2641,19 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
Typ

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-03-07 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Thank you all for looking into this.

Note that I don't have commit access, and I would appreciate it if someone 
merges this if/when it is ready to merge!

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix quadratic slowdown in AST matcher parent map generation (PR #87824)

2025-03-04 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Hello,
This seems to cause a noticeable increase in memory consumption on some 
examples. See 
https://github.com/llvm/llvm-project/issues/129808#issuecomment-2700015065.

https://github.com/llvm/llvm-project/pull/87824
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-27 Thread Michael Jabbour via cfe-commits


@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);

michael-jabbour-sonarsource wrote:

Thank you all very much for checking this. I will be updating the failing test 
in a few hours (or tomorrow).

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-27 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource edited 
https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-23 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Gentle ping :smile:

@vsapsai, @vgvassilev, I think I have responded to your inquiries and added a 
few related questions. Could you have a look?

https://github.com/llvm/llvm-project/pull/114240
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-26 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/8] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c8..70bbb882eb2b1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d..54c4c5f4e5395 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/8] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b1..d53bcf63dd1bd 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487ae..750301a9155d7 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecE

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-26 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/8] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c8..70bbb882eb2b1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d..54c4c5f4e5395 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/8] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b1..d53bcf63dd1bd 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487ae..750301a9155d7 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecE

[clang] [clang] Fix ASTWriter crash after merging named enums (PR #114240)

2025-02-27 Thread Michael Jabbour via cfe-commits

https://github.com/michael-jabbour-sonarsource updated 
https://github.com/llvm/llvm-project/pull/114240

>From cc3cf25da67c9f8b9edabb318c6011cad9bd2f58 Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 11:16:09 +0100
Subject: [PATCH 1/8] [NFC] Factor out RetireNodesFromMergedDecl

---
 clang/include/clang/Sema/Sema.h |  6 ++
 clang/lib/Sema/SemaDecl.cpp | 27 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c8..70bbb882eb2b1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4034,6 +4034,12 @@ class Sema final : public SemaBase {
   void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
 LookupResult &OldDecls);
 
+  /// RetireNodesFromMergedDecl - We have just merged the decl 'New' by making
+  /// another definition visible.
+  /// This method performs any necessary cleanup on the parser state to discard
+  /// child nodes from newly parsed decl we are retiring.
+  void RetireNodesFromMergedDecl(Scope *S, Decl *New);
+
   /// MergeFunctionDecl - We just parsed a function 'New' from
   /// declarator D which has the same name and scope as a previous
   /// declaration 'Old'.  Figure out how to resolve this situation,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d..54c4c5f4e5395 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2551,18 +2551,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   // Make the old tag definition visible.
   makeMergedDefinitionVisible(Hidden);
 
-  // If this was an unscoped enumeration, yank all of its enumerators
-  // out of the scope.
-  if (isa(NewTag)) {
-Scope *EnumScope = getNonFieldDeclScope(S);
-for (auto *D : NewTag->decls()) {
-  auto *ED = cast(D);
-  assert(EnumScope->isDeclScope(ED));
-  EnumScope->RemoveDecl(ED);
-  IdResolver.RemoveDecl(ED);
-  ED->getLexicalDeclContext()->removeDecl(ED);
-}
-  }
+  RetireNodesFromMergedDecl(S, NewTag);
 }
   }
 
@@ -2639,6 +2628,20 @@ void Sema::MergeTypedefNameDecl(Scope *S, 
TypedefNameDecl *New,
   notePreviousDefinition(Old, New->getLocation());
 }
 
+void Sema::RetireNodesFromMergedDecl(Scope *S, Decl *New) {
+  // If this was an unscoped enumeration, yank all of its enumerators
+  // out of the scope.
+  if (auto *ED = dyn_cast(New); ED) {
+Scope *EnumScope = getNonFieldDeclScope(S);
+for (auto *ECD : ED->enumerators()) {
+  assert(EnumScope->isDeclScope(ECD));
+  EnumScope->RemoveDecl(ECD);
+  IdResolver.RemoveDecl(ECD);
+  ECD->getLexicalDeclContext()->removeDecl(ECD);
+}
+  }
+}
+
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool DeclHasAttr(const Decl *D, const Attr *A) {

>From f07904ae5468658a3e7e4a649cd183734479d6cc Mon Sep 17 00:00:00 2001
From: Michael Jabbour 
Date: Tue, 29 Oct 2024 12:07:29 +0100
Subject: [PATCH 2/8] Drop enumerators when merging named enums

This fixes a crash in ASTWriter when the stale IdResolver entries are
used when writing the identifier table.

  assert(DeclIDs.contains(D) && "Declaration not emitted!");
---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseDecl.cpp   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp|  3 +-
 clang/lib/Sema/SemaDecl.cpp |  6 ++-
 clang/test/Modules/modules-merge-enum.m | 52 +
 5 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/modules-merge-enum.m

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70bbb882eb2b1..d53bcf63dd1bd 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3910,7 +3910,7 @@ class Sema final : public SemaBase {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+  bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
 
   typedef void *SkippedDefinitionContext;
 
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487ae..750301a9155d7 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5645,7 +5645,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec &DS,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
   DS.SetTypeSpecE

[clang] [llvm] Revert "[lit][clang] Avoid realpath on Windows due to MAX_PATH limitations" (PR #139739)

2025-05-14 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Thank you very much @compnerd and @tristanlabelle for the information. I am 
writing my thoughts below:

> Everything is being built in S:, there is no reason that the path should be 
> "canonicalised" to %UserProfile%\SourceCache\llvm-project\llvm\... instead of 
> X:\llvm-project which is what you told the tools the path is.

I feel I am missing why being inside `X:` is any different from being inside a 
symlink to another directory. For me, both cases should be treated similarly: 
The canonical path of a file is the one inside `%UserProfile%`. The parts of 
the compiler that don't need the canonical path should always see `X:`, whereas 
the ones that ask for the canonical path should see `%UserProfile%`. Could you 
clarify why should a substituted drive be treated differently from any symlink?

> I agree with that intended definition, but that is not the usage in practice. 
> Code will arbitrarily canonicalize some paths and keep going, rather than 
> using canonicalized paths only for comparisons.

I agree with this, and for me it sounds more like it is a problem in how the 
function is used, not how it behaves. The fix should be to go through the 
usages and make sure they really need to canonicalize IMO.

> I do not know if there is an API that will let you resolve a path into a 
> particular drive, but if so, that would likely be the proper tool to use here.

> In the presence of chains of filesystem decorators, we'll undo the real-path 
> mapping of the entire chain if it changes the drive, whereas we just want the 
> real filesystem at the bottom of the chain to be decorated to avoid changing 
> the drive.

IIUC, both these suggestions aim to address points "1" and "2" in my previous 
response. This might be an improvement over the existing patch (as it would 
start resolving symlinks inside the drive), but concern "3" remains. I would 
still be concerned about calling such functionality a "canonical" path, as it 
doesn't satisfy the canonical property: One may still get different canonical 
paths for the same file, depending on whether they access 
`%UserProfile%/SourceCache/file` and `X:/file`. In other words, I don't agree 
with calling this "root-preserving transformation" a "canonicalization". Could 
you clarify if I am missing something here?

Best regards,
Michael

https://github.com/llvm/llvm-project/pull/139739
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Revert "[lit][clang] Avoid realpath on Windows due to MAX_PATH limitations" (PR #139739)

2025-05-14 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Hello @compnerd, and thank you for sharing the information and for the prompt 
response.

> Without this change, a file on a substituted drive will have two separate 
> paths.

I am not sure I understand this part. For me, a file on a substituted drive (or 
under a symlink) may always have multiple different valid paths to reference 
it. What is important, is that it always has a single canonical path. This is 
the reason I don’t fully see “root-preserving canonicalization” as a form of a 
“canonical path” anymore. To summarize my concerns:

1. The patch seems to work slightly differently from what is described in the 
patch description:

1. It doesn't only avoid resolving the mapped drive as claimed, but it also 
skips the symlink resolution on mapped drives (it only removes dots in that 
case).
2. The impact above is not only limited to substituted/mapped drives, but 
to any case where the roots are not identical (for example, also in cross-drive 
links).

2. It affects clang’s usability as a library. I feel that such fallback should 
be applied on a higher-level API, and ideally should impact only lit tests (as 
they are the motivation stated in the patch). For example, by looking at usages 
in clang, I could find that many of them still assume that 
`FileManager::getCanonicalName` resolves symlinks (at least by looking at the 
comments):

1. clangd’s `SourceCode::getCanonicalPath` which claims to resolve symlinks 
in its docs. IIUC, it no longer does so if the code is checked out in a 
substituted drive (see 
[here](https://github.com/llvm/llvm-project/blob/47c892a49136c68425e7ade08553598e63ef4e70/clang-tools-extra/clangd/SourceCode.cpp#L533)).
2. Inside clang itself, there is code that handles directory resolution in 
module map and framework header search (for example 
[here](https://github.com/llvm/llvm-project/blob/47c892a49136c68425e7ade08553598e63ef4e70/clang/lib/Lex/HeaderSearch.cpp#L573)
 and 
[here](https://github.com/SonarSource/llvm-project/blob/d84668d2b2ec28a5d6f81e6eb22a17b014a000cf/clang/lib/Lex/ModuleMap.cpp#L449)).
 This may not impact Windows users, but I am not entirely sure.

3. Skipping symlink resolution makes it possible for `getCanonicalName` to 
return different paths for the same file (breaking the canonical property, 
which can impact users of clang as a library, depending on how they use it).

Basically, we have concerns about the correctness of all existing usages of 
`getCanonicalName` (inside and outside clang). It also impacted us as users of 
clang as a library. If the motivation is only to fix lit tests, I can see a few 
alternatives:

1. Try to apply such a fix on a higher-level API where needed, to avoid 
unexpected impact? I didn't try to look for such an API myself yet. Do you know 
if this been explored while working on the previous patch?

2. Switch to a solution that adapts the test as needed without altering 
functionality (e.g. prior to what [was explored after this 
comment](https://reviews.llvm.org/D154130#4515403))

3. Revert the patch, and switch to a user-specific workaround which does not 
require changing LLVM (as suggested in this PR). Note that the patch, not only 
alters the behavior of clang, but also breaks the lit setup for some other 
developers on Windows (see [here](https://reviews.llvm.org/D154130#4647550)).

Any thoughts about this are appreciated.

Best regards,
Michael

https://github.com/llvm/llvm-project/pull/139739
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Revert "[lit][clang] Avoid realpath on Windows due to MAX_PATH limitations" (PR #139739)

2025-05-22 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Gentle ping :smile:

I would also appreciate any opinions on my previous comment, maybe this can 
help us align on a solution that satisfies all users...

https://github.com/llvm/llvm-project/pull/139739
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Revert "[lit][clang] Avoid realpath on Windows due to MAX_PATH limitations" (PR #139739)

2025-06-16 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Hi @tristanlabelle and thanks for your response,

> 1. Code pervasively access files through canonicalized paths rather than 
> using canonicalized paths only for identity comparisons. The two usages are 
> often conflated and can't be teased apart easily.

I understand that there are possibly many cases where retrieving the canonical 
path is not strictly needed, yet the code does it anyway. However, changing the 
way canonical path for everyone feels a bit drastic to me, as it can also break 
proper code that uses the canonical path for identity comparisons (especially 
with the current implementation limitations I listed earlier in mind). Could 
you elaborate more about the impact of this problem? Does its severity justify 
such a drastic change?

> 2. Hitting the Windows MAX_PATH limitation is a showstopper (broken builds or 
> tests)

I also understand that without this change the `MAX_PATH` limitation can cause 
problems running the tests on certain environments. However, as I mentioned 
earlier, this change breaks the development environments for other environments 
(see [here](https://reviews.llvm.org/D154130#4647550)).

Furthermore, the change doesn't only fix the tests, but also alters the 
behavior in production. [The following 
comment](https://reviews.llvm.org/D154130#4515403) on phabricator caught my 
attention:

> Update clang path canonicalization to avoid resolving substitute drives (ie 
> resolving to a path under a different root). This requires much less change 
> to tests.

Maybe there is actually another way that relies on changing tests only? Do you 
happen to remember the context here? :smile:

I would also appreciate any other opinions on this.

https://github.com/llvm/llvm-project/pull/139739
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] skip shadow warnings for enum constants in distinct class scopes (PR #115656)

2025-07-02 Thread Michael Jabbour via cfe-commits

michael-jabbour-sonarsource wrote:

Hello,

I think that the following cases used to be valid reports on clang 19, but they 
are not reported in clang 20 after this patch. Is this intended?

```cpp
namespace classEnums {
int globalVar = 0;
class ClassWithEnum {
  enum Enum {
globalVar  // No -Wshadow after this patch.
  };
};

class OuterClass {
  static const int memberData = 0;
  enum Enum {
enumVal
  };
  class InnerClass {
enum Enum {
  memberData,  // No -Wshadow after this patch.
  enumVal  // No -Wshadow after this patch.
};
  };
};
}
```
CE: https://godbolt.org/z/no87EEYxn

@a-tarasyuk, @Fznamznon, @Sirraide

https://github.com/llvm/llvm-project/pull/115656
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits