[clang-tools-extra] [clangd] Avoid libFormat's objective-c guessing heuristic where possible (PR #84133)

2024-03-11 Thread Nathan Ridge via cfe-commits

https://github.com/HighCommander4 updated 
https://github.com/llvm/llvm-project/pull/84133

>From 9c3a4ab81e931f43104fa0ac26de56595f43c6b4 Mon Sep 17 00:00:00 2001
From: Nathan Ridge 
Date: Sun, 25 Feb 2024 19:55:10 -0500
Subject: [PATCH] [clangd] Avoid libFormat's objective-c guessing heuristic
 where possible

This avoids a known libFormat bug where the heuristic can OOM on certain
large files (particularly single-header libraries such as miniaudio.h).

The OOM will still happen on affected files if you actually try to
format them (this is harder to avoid since the underlyting issue affects
the actual formatting logic, not just the language-guessing heuristic),
but at least it's avoided during non-modifying operations like hover, and
modifying operations that do local formatting like code completion.

Fixes https://github.com/clangd/clangd/issues/719
Fixes https://github.com/clangd/clangd/issues/1384
Fixes https://github.com/llvm/llvm-project/issues/70945
---
 clang-tools-extra/clangd/ClangdServer.cpp | 10 ++---
 clang-tools-extra/clangd/CodeComplete.cpp |  4 +-
 clang-tools-extra/clangd/IncludeCleaner.cpp   |  2 +-
 clang-tools-extra/clangd/ParsedAST.cpp|  2 +-
 clang-tools-extra/clangd/SourceCode.cpp   | 16 +++-
 clang-tools-extra/clangd/SourceCode.h |  6 ++-
 clang-tools-extra/clangd/tool/Check.cpp   |  2 +-
 .../clangd/unittests/SourceCodeTests.cpp  | 38 +++
 8 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 2907e3ba3c303c..5790273d625ef1 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -523,7 +523,7 @@ void ClangdServer::formatFile(PathRef File, 
std::optional Rng,
   auto Action = [File = File.str(), Code = std::move(*Code),
  Ranges = std::vector{RequestedRange},
  CB = std::move(CB), this]() mutable {
-format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS);
+format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS, true);
 tooling::Replacements IncludeReplaces =
 format::sortIncludes(Style, Code, Ranges, File);
 auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
@@ -551,7 +551,7 @@ void ClangdServer::formatOnType(PathRef File, Position Pos,
   auto Action = [File = File.str(), Code = std::move(*Code),
  TriggerText = TriggerText.str(), CursorPos = *CursorPos,
  CB = std::move(CB), this]() mutable {
-auto Style = getFormatStyleForFile(File, Code, TFS);
+auto Style = getFormatStyleForFile(File, Code, TFS, false);
 std::vector Result;
 for (const tooling::Replacement &R :
  formatIncremental(Code, CursorPos, TriggerText, Style))
@@ -605,7 +605,7 @@ void ClangdServer::rename(PathRef File, Position Pos, 
llvm::StringRef NewName,
 
 if (Opts.WantFormat) {
   auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
- *InpAST->Inputs.TFS);
+ *InpAST->Inputs.TFS, false);
   llvm::Error Err = llvm::Error::success();
   for (auto &E : R->GlobalChanges)
 Err =
@@ -762,7 +762,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, 
StringRef TweakID,
   for (auto &It : (*Effect)->ApplyEdits) {
 Edit &E = It.second;
 format::FormatStyle Style =
-getFormatStyleForFile(File, E.InitialCode, TFS);
+getFormatStyleForFile(File, E.InitialCode, TFS, false);
 if (llvm::Error Err = reformatEdit(E, Style))
   elog("Failed to format {0}: {1}", It.first(), std::move(Err));
   }
@@ -825,7 +825,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
 if (!InpAST)
   return CB(InpAST.takeError());
 format::FormatStyle Style = getFormatStyleForFile(
-File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS);
+File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false);
 CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
   };
 
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 0e5f08cec440ce..036eb9808ea082 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1628,7 +1628,7 @@ class CodeCompleteFlow {
   IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
   auto Style = getFormatStyleForFile(SemaCCInput.FileName,
  SemaCCInput.ParseInput.Contents,
- *SemaCCInput.ParseInput.TFS);
+ *SemaCCInput.ParseInput.TFS, false);
   const auto NextToken = findTokenAfterCompletionPoint(
   Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
   Recorder->CCSema->getSourceManager(),

[clang-tools-extra] [clangd] Avoid libFormat's objective-c guessing heuristic where possible (PR #84133)

2024-03-11 Thread Nathan Ridge via cfe-commits


@@ -166,14 +166,29 @@ TextEdit toTextEdit(const FixItHint &FixIt, const 
SourceManager &M,
 std::optional getCanonicalPath(const FileEntryRef F,
 FileManager &FileMgr);
 
+/// A flag passed to getFormatStyleForFile() that specifies what kind of
+/// formatting operation the returned FormatStyle will be used for.
+enum class FormatKind {
+  // Formatting a snippet of synthesized code (e.g. a code snippet
+  // shown in a hover) that's not part of the main file.
+  Snippet,
+  // Formatting edits made by an editor action such as code completion
+  // or rename.
+  Replacements,
+  // Formatting the entire main file (or a range selected by the user,
+  // which can be arbitrarily long).
+  EntireFileOrRange

HighCommander4 wrote:

Done, patch uses a bool flag now

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


[clang-tools-extra] [clangd] Avoid libFormat's objective-c guessing heuristic where possible (PR #84133)

2024-03-11 Thread Nathan Ridge via cfe-commits


@@ -166,14 +166,29 @@ TextEdit toTextEdit(const FixItHint &FixIt, const 
SourceManager &M,
 std::optional getCanonicalPath(const FileEntryRef F,
 FileManager &FileMgr);
 
+/// A flag passed to getFormatStyleForFile() that specifies what kind of
+/// formatting operation the returned FormatStyle will be used for.
+enum class FormatKind {
+  // Formatting a snippet of synthesized code (e.g. a code snippet
+  // shown in a hover) that's not part of the main file.
+  Snippet,
+  // Formatting edits made by an editor action such as code completion
+  // or rename.
+  Replacements,
+  // Formatting the entire main file (or a range selected by the user,
+  // which can be arbitrarily long).
+  EntireFileOrRange
+};
+
 /// Choose the clang-format style we should apply to a certain file.
 /// This will usually use FS to look for .clang-format directories.
 /// FIXME: should we be caching the .clang-format file search?
 /// This uses format::DefaultFormatStyle and format::DefaultFallbackStyle,
 /// though the latter may have been overridden in main()!
 format::FormatStyle getFormatStyleForFile(llvm::StringRef File,

HighCommander4 wrote:

Sure, I added a unit test which checks the detected language in various cases, 
including checking that the new `FormatFile` flag successfully bypasses the 
language guessing heuristic

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


[clang-tools-extra] 3093d73 - [clangd] Avoid libFormat's objective-c guessing heuristic where possible (#84133)

2024-03-11 Thread via cfe-commits

Author: Nathan Ridge
Date: 2024-03-11T04:16:45-04:00
New Revision: 3093d731dff93df02899dcc62f5e7ba02461ff2a

URL: 
https://github.com/llvm/llvm-project/commit/3093d731dff93df02899dcc62f5e7ba02461ff2a
DIFF: 
https://github.com/llvm/llvm-project/commit/3093d731dff93df02899dcc62f5e7ba02461ff2a.diff

LOG: [clangd] Avoid libFormat's objective-c guessing heuristic where possible 
(#84133)

This avoids a known libFormat bug where the heuristic can OOM on certain
large files (particularly single-header libraries such as miniaudio.h).

The OOM will still happen on affected files if you actually try to
format them (this is harder to avoid since the underlyting issue affects
the actual formatting logic, not just the language-guessing heuristic),
but at least it's avoided during non-modifying operations like hover,
and modifying operations that do local formatting like code completion.

Fixes https://github.com/clangd/clangd/issues/719
Fixes https://github.com/clangd/clangd/issues/1384
Fixes https://github.com/llvm/llvm-project/issues/70945

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/SourceCode.cpp
clang-tools-extra/clangd/SourceCode.h
clang-tools-extra/clangd/tool/Check.cpp
clang-tools-extra/clangd/unittests/SourceCodeTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 2907e3ba3c303c..5790273d625ef1 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -523,7 +523,7 @@ void ClangdServer::formatFile(PathRef File, 
std::optional Rng,
   auto Action = [File = File.str(), Code = std::move(*Code),
  Ranges = std::vector{RequestedRange},
  CB = std::move(CB), this]() mutable {
-format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS);
+format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS, true);
 tooling::Replacements IncludeReplaces =
 format::sortIncludes(Style, Code, Ranges, File);
 auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
@@ -551,7 +551,7 @@ void ClangdServer::formatOnType(PathRef File, Position Pos,
   auto Action = [File = File.str(), Code = std::move(*Code),
  TriggerText = TriggerText.str(), CursorPos = *CursorPos,
  CB = std::move(CB), this]() mutable {
-auto Style = getFormatStyleForFile(File, Code, TFS);
+auto Style = getFormatStyleForFile(File, Code, TFS, false);
 std::vector Result;
 for (const tooling::Replacement &R :
  formatIncremental(Code, CursorPos, TriggerText, Style))
@@ -605,7 +605,7 @@ void ClangdServer::rename(PathRef File, Position Pos, 
llvm::StringRef NewName,
 
 if (Opts.WantFormat) {
   auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
- *InpAST->Inputs.TFS);
+ *InpAST->Inputs.TFS, false);
   llvm::Error Err = llvm::Error::success();
   for (auto &E : R->GlobalChanges)
 Err =
@@ -762,7 +762,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, 
StringRef TweakID,
   for (auto &It : (*Effect)->ApplyEdits) {
 Edit &E = It.second;
 format::FormatStyle Style =
-getFormatStyleForFile(File, E.InitialCode, TFS);
+getFormatStyleForFile(File, E.InitialCode, TFS, false);
 if (llvm::Error Err = reformatEdit(E, Style))
   elog("Failed to format {0}: {1}", It.first(), std::move(Err));
   }
@@ -825,7 +825,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
 if (!InpAST)
   return CB(InpAST.takeError());
 format::FormatStyle Style = getFormatStyleForFile(
-File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS);
+File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false);
 CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
   };
 

diff  --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 0e5f08cec440ce..036eb9808ea082 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1628,7 +1628,7 @@ class CodeCompleteFlow {
   IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
   auto Style = getFormatStyleForFile(SemaCCInput.FileName,
  SemaCCInput.ParseInput.Contents,
- *SemaCCInput.ParseInput.TFS);
+ *SemaCCInput.ParseInput.TFS, false);
   const auto NextToken = findTokenAfterCompletionPoint(
   Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),

[clang-tools-extra] [clangd] Avoid libFormat's objective-c guessing heuristic where possible (PR #84133)

2024-03-11 Thread Nathan Ridge via cfe-commits

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


[clang] Comment parsing: add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread via cfe-commits

https://github.com/hdoc created https://github.com/llvm/llvm-project/pull/84726

Doxygen allows for the @throw, @throws, and @exception commands to have an 
attached argument indicating the type being thrown. Currently, Clang's AST 
parsing doesn't support parsing out this argument from doc comments. The result 
is missing compatibility with Doxygen.

We would find it helpful if the AST exposed these thrown types as 
BlockCommandComment arguments so that we could generate better documentation.

This PR implements parsing of arguments for the @throw, @throws, and @exception 
commands. Each command can only have one argument, matching the semantics of 
Doxygen. We have also added unit tests to validate the functionality.

>From ec3f444913d9162de4494cdb09b336b1b00380fa Mon Sep 17 00:00:00 2001
From: hdoc 
Date: Mon, 11 Mar 2024 01:13:25 -0700
Subject: [PATCH] Comment parsing: add argument parsing for @throw @throws
 @exception

Doxygen allows for the @throw, @throws, and @exception commands to
have an attached argument indicating the type being thrown. Currently,
Clang's AST parsing doesn't support parsing out this argument from doc
comments. The result is missing compatibility with Doxygen.

We would find it helpful if the AST exposed these thrown types as
BlockCommandComment arguments so that we could generate better
documentation.

This PR implements parsing of arguments for the @throw, @throws, and
@exception commands. Each command can only have one argument, matching
the semantics of Doxygen. We have also added unit tests to validate
the functionality.
---
 clang/include/clang/AST/CommentCommands.td |   6 +-
 clang/include/clang/AST/CommentParser.h|   3 +
 clang/lib/AST/CommentParser.cpp| 133 
 clang/unittests/AST/CommentParser.cpp  | 235 -
 4 files changed, 373 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/CommentCommands.td 
b/clang/include/clang/AST/CommentCommands.td
index e839031752cdd8..06b2fa9b5531c6 100644
--- a/clang/include/clang/AST/CommentCommands.td
+++ b/clang/include/clang/AST/CommentCommands.td
@@ -132,9 +132,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 
1; }
 // HeaderDoc command for template parameter documentation.
 def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
 
-def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; }
-def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
-def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
+def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs 
= 1; }
+def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 
1; }
+def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let 
NumArgs = 1;}
 
 def Deprecated : BlockCommand<"deprecated"> {
   let IsEmptyParagraphAllowed = 1;
diff --git a/clang/include/clang/AST/CommentParser.h 
b/clang/include/clang/AST/CommentParser.h
index e11e818b1af0a1..5884a25d007851 100644
--- a/clang/include/clang/AST/CommentParser.h
+++ b/clang/include/clang/AST/CommentParser.h
@@ -100,6 +100,9 @@ class Parser {
   ArrayRef
   parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
 
+  ArrayRef
+  parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
+
   BlockCommandComment *parseBlockCommand();
   InlineCommandComment *parseInlineCommand();
 
diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp
index 8adfd85d0160c3..c70fa1b05cb241 100644
--- a/clang/lib/AST/CommentParser.cpp
+++ b/clang/lib/AST/CommentParser.cpp
@@ -75,6 +75,25 @@ class TextTokenRetokenizer {
 return *Pos.BufferPtr;
   }
 
+  char peekNext(unsigned offset) const {
+assert(!isEnd());
+assert(Pos.BufferPtr != Pos.BufferEnd);
+if (Pos.BufferPtr + offset <= Pos.BufferEnd) {
+  return *(Pos.BufferPtr + offset);
+} else {
+  return '\0';
+}
+  }
+
+  void peekNextToken(SmallString<32> &WordText) const {
+unsigned offset = 1;
+char C = peekNext(offset++);
+while (!isWhitespace(C) && C != '\0') {
+  WordText.push_back(C);
+  C = peekNext(offset++);
+}
+  }
+
   void consumeChar() {
 assert(!isEnd());
 assert(Pos.BufferPtr != Pos.BufferEnd);
@@ -89,6 +108,29 @@ class TextTokenRetokenizer {
 }
   }
 
+  /// Extract a template type
+  bool lexTemplateType(SmallString<32> &WordText) {
+unsigned IncrementCounter = 0;
+while (!isEnd()) {
+  const char C = peek();
+  WordText.push_back(C);
+  consumeChar();
+  switch (C) {
+  default:
+break;
+  case '<': {
+IncrementCounter++;
+  } break;
+  case '>': {
+IncrementCounter--;
+if (!IncrementCounter)
+  return true;
+  } break;
+  }
+}
+return false;
+  }
+
   /// Add a token.
   /// Returns true on success, false if there are no interesting tokens to
   /// fetch from lexer.

[clang] Comment parsing: add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [clang-format] Limit how much work guessLanguage() can do (PR #78925)

2024-03-11 Thread Nathan Ridge via cfe-commits

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


[clang] [clang-format] Limit how much work guessLanguage() can do (PR #78925)

2024-03-11 Thread Nathan Ridge via cfe-commits

HighCommander4 wrote:

> Thanks. I've written the clangd patch and posted it for review at #84133.
> 
> If that gets approved, I will abandon this PR.

#84133 has merged now. I'll accordingly close this.

Thank you @owenca for your feedback and helping reach a solution that 
accomplished the goals of this patch in a claner way!

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


[clang] Comment parsing: add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: hdoc (hdoc)


Changes

Doxygen allows for the @throw, @throws, and @exception 
commands to have an attached argument indicating the type being thrown. 
Currently, Clang's AST parsing doesn't support parsing out this argument from 
doc comments. The result is missing compatibility with Doxygen.

We would find it helpful if the AST exposed these thrown types as 
BlockCommandComment arguments so that we could generate better documentation.

This PR implements parsing of arguments for the @throw, @throws, and @exception commands. Each command can only have one 
argument, matching the semantics of Doxygen. We have also added unit tests to 
validate the functionality.

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


4 Files Affected:

- (modified) clang/include/clang/AST/CommentCommands.td (+3-3) 
- (modified) clang/include/clang/AST/CommentParser.h (+3) 
- (modified) clang/lib/AST/CommentParser.cpp (+133) 
- (modified) clang/unittests/AST/CommentParser.cpp (+234-1) 


``diff
diff --git a/clang/include/clang/AST/CommentCommands.td 
b/clang/include/clang/AST/CommentCommands.td
index e839031752cdd8..06b2fa9b5531c6 100644
--- a/clang/include/clang/AST/CommentCommands.td
+++ b/clang/include/clang/AST/CommentCommands.td
@@ -132,9 +132,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 
1; }
 // HeaderDoc command for template parameter documentation.
 def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
 
-def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; }
-def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
-def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
+def Throws: BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs 
= 1; }
+def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 
1; }
+def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let 
NumArgs = 1;}
 
 def Deprecated : BlockCommand<"deprecated"> {
   let IsEmptyParagraphAllowed = 1;
diff --git a/clang/include/clang/AST/CommentParser.h 
b/clang/include/clang/AST/CommentParser.h
index e11e818b1af0a1..5884a25d007851 100644
--- a/clang/include/clang/AST/CommentParser.h
+++ b/clang/include/clang/AST/CommentParser.h
@@ -100,6 +100,9 @@ class Parser {
   ArrayRef
   parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
 
+  ArrayRef
+  parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
+
   BlockCommandComment *parseBlockCommand();
   InlineCommandComment *parseInlineCommand();
 
diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp
index 8adfd85d0160c3..c70fa1b05cb241 100644
--- a/clang/lib/AST/CommentParser.cpp
+++ b/clang/lib/AST/CommentParser.cpp
@@ -75,6 +75,25 @@ class TextTokenRetokenizer {
 return *Pos.BufferPtr;
   }
 
+  char peekNext(unsigned offset) const {
+assert(!isEnd());
+assert(Pos.BufferPtr != Pos.BufferEnd);
+if (Pos.BufferPtr + offset <= Pos.BufferEnd) {
+  return *(Pos.BufferPtr + offset);
+} else {
+  return '\0';
+}
+  }
+
+  void peekNextToken(SmallString<32> &WordText) const {
+unsigned offset = 1;
+char C = peekNext(offset++);
+while (!isWhitespace(C) && C != '\0') {
+  WordText.push_back(C);
+  C = peekNext(offset++);
+}
+  }
+
   void consumeChar() {
 assert(!isEnd());
 assert(Pos.BufferPtr != Pos.BufferEnd);
@@ -89,6 +108,29 @@ class TextTokenRetokenizer {
 }
   }
 
+  /// Extract a template type
+  bool lexTemplateType(SmallString<32> &WordText) {
+unsigned IncrementCounter = 0;
+while (!isEnd()) {
+  const char C = peek();
+  WordText.push_back(C);
+  consumeChar();
+  switch (C) {
+  default:
+break;
+  case '<': {
+IncrementCounter++;
+  } break;
+  case '>': {
+IncrementCounter--;
+if (!IncrementCounter)
+  return true;
+  } break;
+  }
+}
+return false;
+  }
+
   /// Add a token.
   /// Returns true on success, false if there are no interesting tokens to
   /// fetch from lexer.
@@ -149,6 +191,76 @@ class TextTokenRetokenizer {
 addToken();
   }
 
+  /// Extract a type argument
+  bool lexDataType(Token &Tok) {
+if (isEnd())
+  return false;
+Position SavedPos = Pos;
+consumeWhitespace();
+SmallString<32> NextToken;
+SmallString<32> WordText;
+const char *WordBegin = Pos.BufferPtr;
+SourceLocation Loc = getSourceLocation();
+StringRef ConstVal = StringRef("const");
+bool ConstPointer = false;
+
+while (!isEnd()) {
+  const char C = peek();
+  if (!isWhitespace(C)) {
+if (C == '<') {
+  if (!lexTemplateType(WordText))
+return false;
+} else {
+  WordText.push_back(C);
+  consumeChar();
+}
+  } else {
+if (WordText.equals(ConstVal)) {
+  Wo

[clang] [Clang][Comments] Add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread via cfe-commits

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


[clang] [clang-format][NFC] Eliminate the IsCpp parameter in all functions (PR #84599)

2024-03-11 Thread via cfe-commits

https://github.com/mydeveloperday approved this pull request.

This looks good to me

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


[clang] [C++20][Coroutines] Lambda-coroutine with operator new in promise_type (PR #84193)

2024-03-11 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

This commit breaks our coroutines library async_simple 
`https://github.com/alibaba/async_simple` and here is a (relative) minimal 
reproducer: https://godbolt.org/z/sG5jzcGEz

The reproducer comes from an implementation for async_simple::Generator 
(https://github.com/alibaba/async_simple/blob/main/async_simple/coro/Generator.h),
 which is basically the same implementation from the paper of `std::generator` 
in c++23. So possibly this may make that crash too. 

I'll revert this patch to avoid the regression now. Sorry for not testing it 
sufficiently.

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #83124)

2024-03-11 Thread via cfe-commits

mahtohappy wrote:

Ping @AaronBallman @cor3ntin @Endilll 

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


[clang] 0f501c3 - Revert "[C++20][Coroutines] Lambda-coroutine with operator new in promise_type (#84193)"

2024-03-11 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-03-11T17:02:43+08:00
New Revision: 0f501c30b9601627c236f9abca8a3befba5dc161

URL: 
https://github.com/llvm/llvm-project/commit/0f501c30b9601627c236f9abca8a3befba5dc161
DIFF: 
https://github.com/llvm/llvm-project/commit/0f501c30b9601627c236f9abca8a3befba5dc161.diff

LOG: Revert "[C++20][Coroutines] Lambda-coroutine with operator new in 
promise_type (#84193)"

This reverts commit 35d3b33ba5c9b90443ac985f2521b78f84b611fe.

See the comments in https://github.com/llvm/llvm-project/pull/84193 for
details

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaCoroutine.cpp
clang/lib/Sema/SemaExprCXX.cpp

Removed: 
clang/test/SemaCXX/gh84064-1.cpp
clang/test/SemaCXX/gh84064-2.cpp



diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 00b3f53f5c1c66..267c79cc057cba 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6752,18 +6752,10 @@ class Sema final {
 SourceLocation RParenLoc);
 
    ActOnCXXThis -  Parse 'this' pointer.
-  ///
-  /// \param ThisRefersToClosureObject Whether to skip the 'this' check for a
-  /// lambda because 'this' refers to the closure object.
-  ExprResult ActOnCXXThis(SourceLocation loc,
-  bool ThisRefersToClosureObject = false);
+  ExprResult ActOnCXXThis(SourceLocation loc);
 
   /// Build a CXXThisExpr and mark it referenced in the current context.
-  ///
-  /// \param ThisRefersToClosureObject Whether to skip the 'this' check for a
-  /// lambda because 'this' refers to the closure object.
-  Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit,
- bool ThisRefersToClosureObject = false);
+  Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit);
   void MarkThisReferenced(CXXThisExpr *This);
 
   /// Try to retrieve the type of the 'this' pointer.

diff  --git a/clang/lib/Sema/SemaCoroutine.cpp 
b/clang/lib/Sema/SemaCoroutine.cpp
index 5206fc7621c7cd..736632857efc36 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -25,7 +25,6 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Overload.h"
 #include "clang/Sema/ScopeInfo.h"
-#include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/SmallSet.h"
 
@@ -1291,21 +1290,8 @@ bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
 static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc,
  SmallVectorImpl &PlacementArgs) {
   if (auto *MD = dyn_cast(&FD)) {
-if (MD->isImplicitObjectMemberFunction()) {
-  ExprResult ThisExpr{};
-
-  if (isLambdaCallOperator(MD) && !MD->isStatic()) {
-Qualifiers ThisQuals = MD->getMethodQualifiers();
-CXXRecordDecl *Record = MD->getParent();
-
-Sema::CXXThisScopeRAII ThisScope(S, Record, ThisQuals,
- Record != nullptr);
-
-ThisExpr = S.ActOnCXXThis(Loc, /*ThisRefersToClosureObject=*/true);
-  } else {
-ThisExpr = S.ActOnCXXThis(Loc);
-  }
-
+if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
+  ExprResult ThisExpr = S.ActOnCXXThis(Loc);
   if (ThisExpr.isInvalid())
 return false;
   ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 88e3d9ced044cb..c34a40fa7c81ac 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1414,8 +1414,7 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const 
bool Explicit,
   return false;
 }
 
-ExprResult Sema::ActOnCXXThis(SourceLocation Loc,
-  bool ThisRefersToClosureObject) {
+ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
   /// C++ 9.3.2: In the body of a non-static member function, the keyword this
   /// is a non-lvalue expression whose value is the address of the object for
   /// which the function is called.
@@ -1435,18 +1434,13 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc,
 return Diag(Loc, diag::err_invalid_this_use) << 0;
   }
 
-  return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false,
-  ThisRefersToClosureObject);
+  return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
 }
 
-Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool 
IsImplicit,
- bool ThisRefersToClosureObject) {
+Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
+ bool IsImplicit) {
   auto *This = CXXThisExpr::Create(Context, Loc, Type, IsImplicit);
-
-  if (!ThisRefersToClosureObject) {
-MarkThisReferenced(This);
-  }
-
+  MarkThisReferenced(This);
   return This;
 }
 

diff  --git a/clang/

[clang] [Clang][C++23] Implement P2448R2: Relaxing some constexpr restrictions (PR #77753)

2024-03-11 Thread Mariya Podchishchaeva via cfe-commits

Fznamznon wrote:

> to fail, which I think is not intentional?

No, it is not. Fails only for c++23 now. I'm looking. 

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


[clang] [C++20][Coroutines] Lambda-coroutine with operator new in promise_type (PR #84193)

2024-03-11 Thread Andreas Fertig via cfe-commits

andreasfertig wrote:

Interesting! I'll see what I can do.

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


[clang] [Clang][Comments] Add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread via cfe-commits

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


[clang] [analyzer] Mention possibility of underflow in array overflow errors (PR #84201)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 



@@ -83,6 +83,8 @@ class StateUpdateReporter {
 AssumedUpperBound = UpperBoundVal;
   }
 
+  bool assumedNonNegative() { return AssumedNonNegative; }

NagyDonat wrote:

I'd prefer to keep the current name because it's more natural if we're looking 
at this from the outside (the get/has variants are awkward because 
`AssumedNonNegative` is not a noun phrase); and it's just an implementation 
detail that this is a getter for a private data member.

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


[clang] [analyzer] Mention possibility of underflow in array overflow errors (PR #84201)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,NagyDonat
 
Message-ID:
In-Reply-To: 


https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/84201

>From 74c7c04cb456c0a058ca36a2ca4ffa4d70d576e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Wed, 6 Mar 2024 18:09:02 +0100
Subject: [PATCH 1/3] [analyzer] Mention possibility of underflow in array
 overflow errors

The checker alpha.security.ArrayBoundV2 performs bounds checking in two
steps: first it checks for underflow, and if it isn't guaranteed then it
assumes that there is no underflow. After this, it checks for overflow,
and if it's guaranteed or the index is tainted then it reports it.

This meant that in situations where overflow and underflow are both
possible (but the index is either tainted or guaranteed to be invalid),
the checker was reporting an overflow error.

This commit modifies the messages printed in these cases to mention the
possibility of an underflow.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 37 +++-
 .../test/Analysis/out-of-bounds-diagnostics.c | 56 ++-
 .../test/Analysis/taint-diagnostic-visitor.c  |  2 +-
 3 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index 29eb932584027d..664d26b00a3cab 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -83,6 +83,8 @@ class StateUpdateReporter {
 AssumedUpperBound = UpperBoundVal;
   }
 
+  bool assumedNonNegative() { return AssumedNonNegative; }
+
   const NoteTag *createNoteTag(CheckerContext &C) const;
 
 private:
@@ -402,7 +404,8 @@ static bool tryDividePair(std::optional &Val1,
 }
 
 static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region,
-   NonLoc Offset, NonLoc Extent, SVal Location) {
+   NonLoc Offset, NonLoc Extent, SVal Location,
+   bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   const auto *EReg = Location.getAsRegion()->getAs();
   assert(EReg && "this checker only handles element access");
@@ -414,6 +417,7 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity();
 
   bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize);
+  const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index";
 
   SmallString<256> Buf;
   llvm::raw_svector_ostream Out(Buf);
@@ -421,10 +425,12 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   if (!ExtentN && !UseByteOffsets)
 Out << "'" << ElemType.getAsString() << "' element in ";
   Out << RegName << " at ";
-  if (OffsetN) {
-Out << (UseByteOffsets ? "byte offset " : "index ") << *OffsetN;
+  if (AssumedNonNegative) {
+Out << "a negative or overflowing " << OffsetOrIndex;
+  } else if (OffsetN) {
+Out << OffsetOrIndex << " " << *OffsetN;
   } else {
-Out << "an overflowing " << (UseByteOffsets ? "byte offset" : "index");
+Out << "an overflowing " << OffsetOrIndex;
   }
   if (ExtentN) {
 Out << ", while it holds only ";
@@ -441,17 +447,19 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   Out << "s";
   }
 
-  return {
-  formatv("Out of bound access to memory after the end of {0}", RegName),
-  std::string(Buf)};
+  return {formatv("Out of bound access to memory {0} {1}",
+  AssumedNonNegative ? "around" : "after the end of", RegName),
+  std::string(Buf)};
 }
 
-static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName) {
+static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName,
+ bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   return {formatv("Potential out of bound access to {0} with tainted {1}",
   RegName, OffsetName),
-  formatv("Access of {0} with a tainted {1} that may be too large",
-  RegName, OffsetName)};
+  formatv("Access of {0} with a tainted {1} that may be {2}too large",
+  RegName, OffsetName,
+  AssumedNonNegative ? "negative or " : "")};
 }
 
 const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const {
@@ -603,6 +611,8 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, 
CheckerContext &C) const {
 auto [WithinUpperBound, ExceedsUpperBound] =
 compareValueToThreshold(State, ByteOffset, *KnownSize, SVB);
 
+bool AssumedNonNegative = SUR.assumedNonNegative();
+
 if (ExceedsUpperBound) {
   // The offset may be invalid (>= Size)...
   if (!WithinUpperBound) {
@@ -615,8 +625,9 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, 
CheckerContext &C) const {

[clang] [Clang][Sema] Allow access to a public template alias declaration that refers to friend's private nested type (PR #83847)

2024-03-11 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

gently ping~

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


[clang] [llvm] [WebAssembly] Implement an alternative translation for -wasm-enable-sjlj (PR #84137)

2024-03-11 Thread YAMAMOTO Takashi via cfe-commits

yamt wrote:

> > Given that we don't need `setjmpTableSize` anymore and `setjmpTable` 
> > doesn't change, we don't need the whole block here from line 1463 ~ line 
> > 1503 doing SSA updates anymore:
> 
> i get errors like the following if i simply put the SSA update things in 
> `!EnableWasmAltSjLj` block. i need to investigate.
> 
> ```
> spacetanuki% /Volumes/PortableSSD/llvm/build/bin/clang --sysroot 
> /opt/wasi-sdk-21.0/share/wasi-sysroot -resource-dir 
> /Volumes/PortableSSD/llvm/llvm/lib/clang/17 --target=wasm32-wasi -Os -c 
> -mllvm -wasm-enable-sjlj -mllvm -experimental-wasm-enable-alt-sjlj a.c  
> Instruction does not dominate all uses!
>   %val = load i32, ptr %val_gep, align 4
>   %setjmp.ret = phi i32 [ 0, %entry.split ], [ %val, %setjmp.dispatch ]
> in function f
> fatal error: error in backend: Broken function found, compilation aborted!
> PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
> and include the crash backtrace, preprocessed source, and associated run 
> script.
> Stack dump:
> 0.  Program arguments: /Volumes/PortableSSD/llvm/build/bin/clang 
> --sysroot /opt/wasi-sdk-21.0/share/wasi-sysroot -resource-dir 
> /Volumes/PortableSSD/llvm/llvm/lib/clang/17 --target=wasm32-wasi -Os -c 
> -mllvm -wasm-enable-sjlj -mllvm -experimental-wasm-enable-alt-sjlj a.c
> 1.   parser at end of file
> 2.  Code generation
> 3.  Running pass 'Function Pass Manager' on module 'a.c'.
> 4.  Running pass 'Module Verifier' on function '@f'
> ```

i think i found the cause. rebuildSSA is still necessary to propagate "val".


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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits

https://github.com/11happy updated 
https://github.com/llvm/llvm-project/pull/84481

>From 8fdf6306085ed4cf0f77b7e718e374e9f65fedf9 Mon Sep 17 00:00:00 2001
From: 11happy 
Date: Fri, 8 Mar 2024 19:02:47 +0530
Subject: [PATCH 1/2] add clang-tidy check readability-math-missing-parentheses

Signed-off-by: 11happy 
---
 .../clang-tidy/readability/CMakeLists.txt |   1 +
 .../MathMissingParenthesesCheck.cpp   | 167 ++
 .../readability/MathMissingParenthesesCheck.h |  31 
 .../readability/ReadabilityTidyModule.cpp |   3 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../readability/math-missing-parentheses.rst  |  19 ++
 .../readability/math-missing-parentheses.cpp  |  42 +
 8 files changed, 270 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index a6c8cbd8eb448a..0d4fa095501dfb 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule
   IsolateDeclarationCheck.cpp
   MagicNumbersCheck.cpp
   MakeMemberFunctionConstCheck.cpp
+  MathMissingParenthesesCheck.cpp
   MisleadingIndentationCheck.cpp
   MisplacedArrayIndexCheck.cpp
   NamedParameterCheck.cpp
diff --git 
a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp
new file mode 100644
index 00..d9574a9fb7a476
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp
@@ -0,0 +1,167 @@
+//===--- MathMissingParenthesesCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MathMissingParenthesesCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())),
+hasDescendant(binaryOperator()))
+ .bind("binOp"),
+ this);
+}
+static int precedenceCheck(const char op) {
+  if (op == '/' || op == '*' || op == '%')
+return 5;
+
+  else if (op == '+' || op == '-')
+return 4;
+
+  else if (op == '&')
+return 3;
+  else if (op == '^')
+return 2;
+
+  else if (op == '|')
+return 1;
+
+  else
+return 0;
+}
+static bool isOperand(const char c) {
+  if (c >= 'a' && c <= 'z')
+return true;
+  else if (c >= 'A' && c <= 'Z')
+return true;
+  else if (c >= '0' && c <= '9')
+return true;
+  else if (c == '$')
+return true;
+  else
+return false;
+}
+static bool conditionForNegative(const std::string s, int i,
+ const std::string CurStr) {
+  if (CurStr[0] == '-') {
+if (i == 0) {
+  return true;
+} else {
+  while (s[i - 1] == ' ') {
+i--;
+  }
+  if (!isOperand(s[i - 1])) {
+return true;
+  } else {
+return false;
+  }
+}
+  } else {
+return false;
+  }
+}
+static std::string getOperationOrder(std::string s, std::set &Operators) 
{
+  std::stack StackOne;
+  std::string TempStr = "";
+  for (int i = 0; i < s.length(); i++) {
+std::string CurStr = "";
+CurStr += s[i];
+if (CurStr == " ")
+  continue;
+else {
+  if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) {
+while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) {
+  if (s[i] == '-') {
+TempStr += "$";
+  } else {
+TempStr += CurStr;
+  }
+  i++;
+  CurStr = s[i];
+}
+TempStr += " ";
+  } else if (CurStr == "(") {
+StackOne.push("(");
+  } else if (CurStr == ")") {
+while (StackOne.top() != "(") {
+  TempStr += StackOne.top();
+  StackOne.pop();
+}
+StackOne.pop();
+  } else {
+while (!StackOne.empty() && precedenceCheck

[clang] Add new flag -Wreturn-mismatch (PR #82872)

2024-03-11 Thread Bhuminjay Soni via cfe-commits

11happy wrote:

Are there any more changes for this PR required from my end?
Thank you

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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,167 @@
+//===--- MathMissingParenthesesCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MathMissingParenthesesCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())),
+hasDescendant(binaryOperator()))
+ .bind("binOp"),
+ this);
+}
+static int precedenceCheck(const char op) {
+  if (op == '/' || op == '*' || op == '%')
+return 5;
+
+  else if (op == '+' || op == '-')
+return 4;
+
+  else if (op == '&')
+return 3;
+  else if (op == '^')
+return 2;
+
+  else if (op == '|')
+return 1;
+
+  else
+return 0;
+}
+static bool isOperand(const char c) {

11happy wrote:

done


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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,167 @@
+//===--- MathMissingParenthesesCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MathMissingParenthesesCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())),
+hasDescendant(binaryOperator()))
+ .bind("binOp"),
+ this);
+}
+static int precedenceCheck(const char op) {
+  if (op == '/' || op == '*' || op == '%')
+return 5;
+
+  else if (op == '+' || op == '-')
+return 4;
+
+  else if (op == '&')
+return 3;
+  else if (op == '^')
+return 2;
+
+  else if (op == '|')
+return 1;
+
+  else
+return 0;
+}

11happy wrote:

done

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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,167 @@
+//===--- MathMissingParenthesesCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MathMissingParenthesesCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())),
+hasDescendant(binaryOperator()))
+ .bind("binOp"),
+ this);
+}
+static int precedenceCheck(const char op) {
+  if (op == '/' || op == '*' || op == '%')
+return 5;
+
+  else if (op == '+' || op == '-')
+return 4;
+
+  else if (op == '&')
+return 3;
+  else if (op == '^')
+return 2;
+
+  else if (op == '|')
+return 1;
+
+  else
+return 0;
+}
+static bool isOperand(const char c) {
+  if (c >= 'a' && c <= 'z')
+return true;
+  else if (c >= 'A' && c <= 'Z')
+return true;
+  else if (c >= '0' && c <= '9')
+return true;
+  else if (c == '$')
+return true;
+  else
+return false;
+}
+static bool conditionForNegative(const std::string s, int i,
+ const std::string CurStr) {
+  if (CurStr[0] == '-') {
+if (i == 0) {
+  return true;
+} else {
+  while (s[i - 1] == ' ') {
+i--;
+  }
+  if (!isOperand(s[i - 1])) {
+return true;
+  } else {
+return false;
+  }
+}
+  } else {
+return false;
+  }
+}
+static std::string getOperationOrder(std::string s, std::set &Operators) 
{

11happy wrote:

done

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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,167 @@
+//===--- MathMissingParenthesesCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MathMissingParenthesesCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())),
+hasDescendant(binaryOperator()))
+ .bind("binOp"),
+ this);
+}
+static int precedenceCheck(const char op) {
+  if (op == '/' || op == '*' || op == '%')
+return 5;
+
+  else if (op == '+' || op == '-')
+return 4;
+
+  else if (op == '&')
+return 3;
+  else if (op == '^')
+return 2;
+
+  else if (op == '|')
+return 1;
+
+  else
+return 0;
+}
+static bool isOperand(const char c) {
+  if (c >= 'a' && c <= 'z')
+return true;
+  else if (c >= 'A' && c <= 'Z')
+return true;
+  else if (c >= '0' && c <= '9')
+return true;
+  else if (c == '$')
+return true;
+  else
+return false;
+}
+static bool conditionForNegative(const std::string s, int i,
+ const std::string CurStr) {
+  if (CurStr[0] == '-') {
+if (i == 0) {
+  return true;
+} else {
+  while (s[i - 1] == ' ') {
+i--;
+  }
+  if (!isOperand(s[i - 1])) {
+return true;
+  } else {
+return false;
+  }
+}
+  } else {
+return false;
+  }
+}
+static std::string getOperationOrder(std::string s, std::set &Operators) 
{
+  std::stack StackOne;
+  std::string TempStr = "";
+  for (int i = 0; i < s.length(); i++) {
+std::string CurStr = "";
+CurStr += s[i];
+if (CurStr == " ")
+  continue;
+else {
+  if (isOperand(CurStr[0]) || conditionForNegative(s, i, CurStr)) {
+while (i < s.length() && (isOperand(s[i]) || s[i] == '-')) {
+  if (s[i] == '-') {
+TempStr += "$";
+  } else {
+TempStr += CurStr;
+  }
+  i++;
+  CurStr = s[i];
+}
+TempStr += " ";
+  } else if (CurStr == "(") {
+StackOne.push("(");
+  } else if (CurStr == ")") {
+while (StackOne.top() != "(") {
+  TempStr += StackOne.top();
+  StackOne.pop();
+}
+StackOne.pop();
+  } else {
+while (!StackOne.empty() && precedenceCheck(CurStr[0]) <=
+precedenceCheck((StackOne.top())[0])) {
+  TempStr += StackOne.top();
+  StackOne.pop();
+}
+StackOne.push(CurStr);
+  }
+}
+  }
+  while (!StackOne.empty()) {
+TempStr += StackOne.top();
+StackOne.pop();
+  }
+  std::stack StackTwo;
+  for (int i = 0; i < TempStr.length(); i++) {
+if (TempStr[i] == ' ')
+  continue;
+else if (isOperand(TempStr[i])) {
+  std::string CurStr = "";
+  while (i < TempStr.length() && isOperand(TempStr[i])) {
+if (TempStr[i] == '$') {
+  CurStr += "-";
+} else {
+  CurStr += TempStr[i];
+}
+i++;
+  }
+  StackTwo.push(CurStr);
+} else {
+  std::string OperandOne = StackTwo.top();
+  StackTwo.pop();
+  std::string OperandTwo = StackTwo.top();
+  StackTwo.pop();
+  Operators.insert(TempStr[i]);
+  StackTwo.push("(" + OperandTwo + " " + TempStr[i] + " " + OperandOne +
+")");
+}
+  }
+  return StackTwo.top();
+}
+void MathMissingParenthesesCheck::check(
+const MatchFinder::MatchResult &Result) {
+  const auto *BinOp = Result.Nodes.getNodeAs("binOp");
+  if (!BinOp)
+return;
+  clang::SourceManager &SM = *Result.SourceManager;
+  clang::LangOptions LO = Result.Context->getLangOpts();
+  clang::CharSourceRange Range =
+  clang::CharSourceRange::getTokenRange(BinOp->getSourceRange());
+  std::string Expression = clang::Lexer::getSourceText(Range, SM, LO).str();

11happy wrote:

done

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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -100,6 +100,12 @@ Improvements to clang-tidy
 New checks
 ^^
 
+- New :doc:`readability-math-missing-parentheses
+  ` check.
+
+  Checks for mathematical expressions that involve operators
+  of different priorities.

11happy wrote:

done

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


[clang-tools-extra] Add clang-tidy check readability-math-missing-parentheses (PR #84481)

2024-03-11 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t
+
+// FIXME: Add something that triggers the check here.
+void f(){
+//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the 
precedence of operations [readability-math-missing-parentheses]
+//CHECK-FIXES: int a = 1 + (2 * 3);
+int a = 1 + 2 * 3; 
+
+int b = 1 + 2 + 3; // No warning
+
+int c = 1 * 2 * 3; // No warning
+
+//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the 
precedence of operations [readability-math-missing-parentheses]
+//CHECK-FIXES: int d = (1 + (2 * 3)) - (4 / 5);
+int d = 1 + 2 * 3 - 4 / 5;
+
+//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the 
precedence of operations [readability-math-missing-parentheses]
+//CHECK-FIXES: int e = (1 & (2 + 3)) | (4 * 5);
+int e = 1 & 2 + 3 | 4 * 5;
+
+//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the 
precedence of operations [readability-math-missing-parentheses]
+//CHECK-FIXES: int f = (1 * -2) + 4;
+int f = 1 * -2 + 4;
+
+//CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify the 
precedence of operations [readability-math-missing-parentheses]
+//CHECK-FIXES: int g = (((1 * 2) * 3) + 4) + 5;
+int g = 1 * 2 * 3 + 4 + 5;
+
+// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify 
the precedence of operations [readability-math-missing-parentheses]
+// CHECK-FIXES: int h = (120 & (2 + 3)) | (22 * 5);
+int h = 120 & 2 + 3 | 22 * 5;
+
+int i = 1 & 2 & 3; // No warning
+
+int j = 1 | 2 | 3; // No warning
+
+int k = 1 ^ 2 ^ 3; // No warning
+
+// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: add parantheses to clarify 
the precedence of operations [readability-math-missing-parentheses]
+// CHECK-FIXES: int l = (1 + 2) ^ 3;
+int l = 1 + 2 ^ 3;
+}

11happy wrote:

added tests

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


[clang] [clang] Fix OMPT ident flag in combined distribute parallel for pragma (PR #80987)

2024-03-11 Thread via cfe-commits

mikaoP wrote:

Tests passing now

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


[clang] [Clang][C++23] Implement P2448R2: Relaxing some constexpr restrictions (PR #77753)

2024-03-11 Thread Mariya Podchishchaeva via cfe-commits

Fznamznon wrote:

Ok, now I looked at it a bit more, and I think this is expected due to the 
change and how clang behaved before this patch. After this patch implicit 
destructor of S, i.e. `~S` becomes `constexpr`. It used to be not `constexpr` 
because neither `P` nor `B` had `constexpr` destructors. clang defines and 
emits errors for constexpr defaulted members due to this bit here:
https://github.com/llvm/llvm-project/blob/0ef61ed54dca2e974928c55b2144b57d4c4ff621/clang/lib/Sema/SemaDeclCXX.cpp#L7225

So, once I manually change this example to force `~S()` to be `constexpr`, 
older clang produces the same error:
```
template struct P {
cosntexpr ~P() { p->f(); } // add constexpr
T * p;
};
struct X;
struct B { virtual constexpr ~B(); }; // add constexpr
struct S: B { P x; }; // now all bases and members have constexpr 
destructors, ~S() is constexpr
```
Demo https://godbolt.org/z/rT3bWMdqz (note I took 18.1.0 clang which doesn't 
have P2448R2 implementation). 

I'm not quite sure the error itself is correct, I've got to educate myself 
about standard matters a bit more to understand this, but no other compiler 
errors on this https://godbolt.org/z/Ehhn5sno7.

cc @AaronBallman , @cor3ntin, @zygoloid in case you can weigh in here

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


[clang] [llvm] [WebAssembly] Implement an alternative translation for -wasm-enable-sjlj (PR #84137)

2024-03-11 Thread YAMAMOTO Takashi via cfe-commits

https://github.com/yamt updated https://github.com/llvm/llvm-project/pull/84137

>From 1283ae6b5536810f8fbe183eda80997aa9f5cdc3 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi 
Date: Fri, 9 Feb 2024 15:49:55 +0900
Subject: [PATCH 1/7] [WebAssembly] Implement an alternative translation for
 -wasm-enable-sjlj

Instead of maintaining per-function-invocation malloc()'ed tables to
track which functions each label belongs to, store the equivalent info
in jump buffers (jmp_buf) themselves.

Also, use a less emscripten-looking ABI symbols:

saveSetjmp -> __wasm_sjlj_setjmp
testSetjmp -> __wasm_sjlj_test
getTempRet0-> (removed)
__wasm_longjmp -> __wasm_sjlj_longjmp

Enabled with:

-mllvm -wasm-enable-sjlj -mllvm -experimental-wasm-enable-alt-sjlj

(-experimental-wasm-enable-alt-sjlj is the new option this change
introduces.)

While I want to use this for WASI, it should work for emscripten as well.

An example runtime and a few tests:
https://github.com/yamt/garbage/tree/wasm-sjlj-alt2/wasm/longjmp

Discussion:
https://docs.google.com/document/d/1ZvTPT36K5jjiedF8MCXbEmYjULJjI723aOAks1IdLLg/edit
---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  14 ++
 .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp  |   3 +
 .../MCTargetDesc/WebAssemblyMCTargetDesc.h|   1 +
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp  | 174 +++---
 .../WebAssembly/WebAssemblyTargetMachine.cpp  |   4 +
 5 files changed, 131 insertions(+), 65 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index b8c2573d6265fb..2e7c8e6e8d13f7 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -386,6 +386,20 @@ void WebAssembly::addClangTargetOptions(const ArgList 
&DriverArgs,
   // Backend needs '-exception-model=wasm' to use Wasm EH instructions
   CC1Args.push_back("-exception-model=wasm");
 }
+
+if (Opt.starts_with("-experimental-wasm-enable-alt-sjlj")) {
+  // '-mllvm -experimental-wasm-enable-alt-sjlj'  should be used with
+  // '-mllvm -wasm-enable-sjlj'
+  bool HasWasmEnableSjlj = false;
+  for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
+if (StringRef(A->getValue(0)) == "-wasm-enable-sjlj")
+  HasWasmEnableSjlj = true;
+  }
+  if (!HasWasmEnableSjlj)
+getDriver().Diag(diag::err_drv_argument_only_allowed_with)
+<< "-mllvm -experimental-wasm-enable-alt-sjlj"
+<< "-mllvm -wasm-enable-sjlj";
+}
   }
 }
 
diff --git 
a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp 
b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
index e8f58a19d25e3b..7f15742367be09 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -54,6 +54,9 @@ cl::opt
 // setjmp/longjmp handling using wasm EH instrutions
 cl::opt WebAssembly::WasmEnableSjLj(
 "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
+cl::opt WebAssembly::WasmEnableAltSjLj(
+"experimental-wasm-enable-alt-sjlj",
+cl::desc("Use experimental alternate ABI for --wasm-enable-sjlj"));
 
 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
   const Triple &TT,
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h 
b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 15aeaaeb8c4a4e..d23de9d407d894 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -44,6 +44,7 @@ extern cl::opt WasmEnableEmEH;   // asm.js-style EH
 extern cl::opt WasmEnableEmSjLj; // asm.js-style SjLJ
 extern cl::opt WasmEnableEH; // EH using Wasm EH instructions
 extern cl::opt WasmEnableSjLj;   // SjLj using Wasm EH instructions
+extern cl::opt WasmEnableAltSjLj; // Alt ABI for WasmEnableSjLj
 
 enum OperandType {
   /// Basic block label in a branch construct.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 77e6640d5a8224..fc76757011f5d8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -300,6 +300,7 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public 
ModulePass {
   bool EnableEmEH; // Enable Emscripten exception handling
   bool EnableEmSjLj;   // Enable Emscripten setjmp/longjmp handling
   bool EnableWasmSjLj; // Enable Wasm setjmp/longjmp handling
+  bool EnableWasmAltSjLj; // Alt ABI for EnableWasmSjLj
   bool DoSjLj; // Whether we actually perform setjmp/longjmp handling
 
   GlobalVariable *ThrewGV = nullptr;  // __THREW__ (Emscripten)
@@ -368,7 +369,8 @@ class WebAssemblyLowerEm

[clang] [clang-format] adds a space after not inside macros (PR #78176)

2024-03-11 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

I just wanted to bring up that using `WhitespaceSensitiveMacros` here is a 
little tricky because the macro name one would need to put there is `V` (the 
name is taken directly from the code that hit this).
Having a more sophisticated option to say "parameter `V` of macro 
`MyComplicatedMacro` is a string-sensitive macro" should work better, but seems 
like an overkill. 

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


[clang] ec2875c - [clang-repl] Expose RuntimeInterfaceBuilder to allow customization (#83126)

2024-03-11 Thread via cfe-commits

Author: Stefan Gränitz
Date: 2024-03-11T12:15:11+01:00
New Revision: ec2875ce2690010f7dd894c9b56802297dd6cb84

URL: 
https://github.com/llvm/llvm-project/commit/ec2875ce2690010f7dd894c9b56802297dd6cb84
DIFF: 
https://github.com/llvm/llvm-project/commit/ec2875ce2690010f7dd894c9b56802297dd6cb84.diff

LOG: [clang-repl] Expose RuntimeInterfaceBuilder to allow customization (#83126)

RuntimeInterfaceBuilder wires up JITed expressions with the hardcoded
Interpreter runtime. It's used only for value printing right now, but it
is not limited to that. The default implementation focuses on an
evaluation process where the Interpreter has direct access to the memory
of JITed expressions (in-process execution or shared memory).

We need a different approach to support out-of-process evaluation or
variations of the runtime. It seems reasonable to expose a minimal
interface for it. The new RuntimeInterfaceBuilder is an abstract base
class in the public header. For that, the TypeVisitor had to become a
component (instead of inheriting from it). FindRuntimeInterface() was
adjusted to return an instance of the RuntimeInterfaceBuilder and it can
be overridden from derived classes.

Added: 
clang/unittests/Interpreter/InterpreterExtensionsTest.cpp

Modified: 
clang/include/clang/Interpreter/Interpreter.h
clang/lib/Interpreter/Interpreter.cpp
clang/unittests/Interpreter/CMakeLists.txt

Removed: 




diff  --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index c8f932e95c4798..d972d960dcb7cd 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -18,6 +18,7 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Interpreter/Value.h"
+#include "clang/Sema/Ownership.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
@@ -75,17 +76,26 @@ class IncrementalCompilerBuilder {
   llvm::StringRef CudaSDKPath;
 };
 
+/// Generate glue code between the Interpreter's built-in runtime and user 
code.
+class RuntimeInterfaceBuilder {
+public:
+  virtual ~RuntimeInterfaceBuilder() = default;
+
+  using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
+   Expr *, ArrayRef);
+  virtual TransformExprFunction *getPrintValueTransformer() = 0;
+};
+
 /// Provides top-level interfaces for incremental compilation and execution.
 class Interpreter {
   std::unique_ptr TSCtx;
   std::unique_ptr IncrParser;
   std::unique_ptr IncrExecutor;
+  std::unique_ptr RuntimeIB;
 
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
-  Interpreter(std::unique_ptr CI, llvm::Error &Err);
-
   llvm::Error CreateExecutor();
   unsigned InitPTUSize = 0;
 
@@ -94,8 +104,25 @@ class Interpreter {
   // printing happens, it's in an invalid state.
   Value LastValue;
 
+  // Add a call to an Expr to report its result. We query the function from
+  // RuntimeInterfaceBuilder once and store it as a function pointer to avoid
+  // frequent virtual function calls.
+  RuntimeInterfaceBuilder::TransformExprFunction *AddPrintValueCall = nullptr;
+
+protected:
+  // Derived classes can make use an extended interface of the Interpreter.
+  // That's useful for testing and out-of-tree clients.
+  Interpreter(std::unique_ptr CI, llvm::Error &Err);
+
+  // Lazily construct the RuntimeInterfaceBuilder. The provided instance will 
be
+  // used for the entire lifetime of the interpreter. The default 
implementation
+  // targets the in-process __clang_Interpreter runtime. Override this to use a
+  // custom runtime.
+  virtual std::unique_ptr FindRuntimeInterface();
+
 public:
-  ~Interpreter();
+  virtual ~Interpreter();
+
   static llvm::Expected>
   create(std::unique_ptr CI);
   static llvm::Expected>
@@ -143,8 +170,6 @@ class Interpreter {
 private:
   size_t getEffectivePTUSize() const;
 
-  bool FindRuntimeInterface();
-
   llvm::DenseMap Dtors;
 
   llvm::SmallVector ValuePrintingInfo;

diff  --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 37696b28976428..3485da8196683a 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -507,9 +507,13 @@ static constexpr llvm::StringRef MagicRuntimeInterface[] = 
{
 "__clang_Interpreter_SetValueWithAlloc",
 "__clang_Interpreter_SetValueCopyArr", "__ci_newtag"};
 
-bool Interpreter::FindRuntimeInterface() {
+static std::unique_ptr
+createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx,
+   Sema &S);
+
+std::unique_ptr Interpreter::FindRuntimeInterface() {
   if (llvm::all_of(ValuePrintingInfo, [](Expr *E) { return E != nullptr; }))
-return true;
+return nullptr;
 
   Sema &S = getCompilerInstance()->getSem

[clang] [clang-repl] Expose RuntimeInterfaceBuilder to allow customization (PR #83126)

2024-03-11 Thread Stefan Gränitz via cfe-commits

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


[clang] [clang-format] adds a space after not inside macros (PR #78176)

2024-03-11 Thread Ilya Biryukov via cfe-commits


@@ -4842,7 +4842,7 @@ bool TokenAnnotator::spaceRequiredBefore(const 
AnnotatedLine &Line,
 return true;
   }
   if (Left.is(TT_UnaryOperator)) {
-if (Right.isNot(tok::l_paren)) {
+if (!Right.isOneOf(tok::r_paren, tok::l_paren, tok::exclaim)) {

ilya-biryukov wrote:

Adding a space makes total sense in code that **has an argument** to `not`.
But this case seems special because `V(not!)` or `V(not)` clearly can't be a 
full expression by themselves. So it feels preferable to not add any extra 
spaces.

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


[clang] [Clang][Comments] Add argument parsing for @throw @throws @exception (PR #84726)

2024-03-11 Thread Krystian Stasiowski via cfe-commits


@@ -149,6 +191,76 @@ class TextTokenRetokenizer {
 addToken();
   }
 
+  /// Extract a type argument
+  bool lexDataType(Token &Tok) {
+if (isEnd())
+  return false;
+Position SavedPos = Pos;
+consumeWhitespace();
+SmallString<32> NextToken;
+SmallString<32> WordText;
+const char *WordBegin = Pos.BufferPtr;
+SourceLocation Loc = getSourceLocation();
+StringRef ConstVal = StringRef("const");

sdkrystian wrote:

Shouldn't we support `volatile` as well?

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


[clang] [Clang][Sema] Fix crash when using name of UnresolvedUsingValueDecl with template arguments (PR #83842)

2024-03-11 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@wlei-llvm Thank you! I've reduced the repro to this:
```cpp
struct A { };

template
void f(A);

struct B {
  void f();

  void g() {
f(A());
  }
};
```

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


[clang] [APINotes] Fix failing tests after a PCM logic change (PR #84556)

2024-03-11 Thread Egor Zhdan via cfe-commits

egorzhdan wrote:

The clang-format CI failure is unrelated to this patch.

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


[clang] 878097d - [APINotes] Fix failing tests after a PCM logic change

2024-03-11 Thread via cfe-commits

Author: Egor Zhdan
Date: 2024-03-11T12:02:29Z
New Revision: 878097dff3ea4bad6b7f50017224a84bbf2af406

URL: 
https://github.com/llvm/llvm-project/commit/878097dff3ea4bad6b7f50017224a84bbf2af406
DIFF: 
https://github.com/llvm/llvm-project/commit/878097dff3ea4bad6b7f50017224a84bbf2af406.diff

LOG: [APINotes] Fix failing tests after a PCM logic change

This fixes tests that are going to be upstreamed in the near future.
Currently they are failing downstream in the Apple open source fork.

Failing tests
  Clang :: APINotes/retain-count-convention.m
  Clang :: APINotes/types.m
  Clang :: APINotes/versioned-multi.c
  Clang :: APINotes/versioned.m

Since 2e5af56 got merged, Clang now enables `LangOpts.APINotesModules`
when reading a precompiled module that was built with API Notes enabled.
This is correct. The logic in APINotesManager needs to be adjusted to
handle this.

rdar://123526142

Added: 


Modified: 
clang/lib/APINotes/APINotesManager.cpp

Removed: 




diff  --git a/clang/lib/APINotes/APINotesManager.cpp 
b/clang/lib/APINotes/APINotesManager.cpp
index d3aef09dac9105..f60f09e2b3c231 100644
--- a/clang/lib/APINotes/APINotesManager.cpp
+++ b/clang/lib/APINotes/APINotesManager.cpp
@@ -224,7 +224,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool 
LookInModule,
   llvm::SmallVector APINotes;
 
   // First, look relative to the module itself.
-  if (LookInModule) {
+  if (LookInModule && M->Directory) {
 // Local function to try loading an API notes file in the given directory.
 auto tryAPINotes = [&](DirectoryEntryRef Dir, bool WantPublic) {
   if (auto File = findAPINotesFile(Dir, ModuleName, WantPublic)) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [APINotes] Fix failing tests after a PCM logic change (PR #84556)

2024-03-11 Thread Egor Zhdan via cfe-commits

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


[clang-tools-extra] [clangd] Fix JSON conversion for symbol tags (PR #84747)

2024-03-11 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/84747

The wrong constructor of json::Value got called, making every tag an array 
instead of a number.

>From f67994902314acd8ae0f0c561b07b8c014172e17 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 11 Mar 2024 13:04:21 +0100
Subject: [PATCH] [clangd] Fix JSON conversion for symbol tags

The wrong constructor of json::Value got called, making every tag an
array instead of a number.
---
 clang-tools-extra/clangd/Protocol.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index 8aa18bb0058abe..c6553e00dcae28 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, 
ReferenceParams &R,
 }
 
 llvm::json::Value toJSON(SymbolTag Tag) {
-  return llvm::json::Value{static_cast(Tag)};
+  return llvm::json::Value(static_cast(Tag));
 }
 
 llvm::json::Value toJSON(const CallHierarchyItem &I) {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Fix JSON conversion for symbol tags (PR #84747)

2024-03-11 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clangd

@llvm/pr-subscribers-clang-tools-extra

Author: Christian Kandeler (ckandeler)


Changes

The wrong constructor of json::Value got called, making every tag an array 
instead of a number.

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


1 Files Affected:

- (modified) clang-tools-extra/clangd/Protocol.cpp (+1-1) 


``diff
diff --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index 8aa18bb0058abe..c6553e00dcae28 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, 
ReferenceParams &R,
 }
 
 llvm::json::Value toJSON(SymbolTag Tag) {
-  return llvm::json::Value{static_cast(Tag)};
+  return llvm::json::Value(static_cast(Tag));
 }
 
 llvm::json::Value toJSON(const CallHierarchyItem &I) {

``




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


[clang-tools-extra] [clangd] Fix JSON conversion for symbol tags (PR #84747)

2024-03-11 Thread Sam McCall via cfe-commits

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


[clang-tools-extra] 9b2386e - [clangd] Fix JSON conversion for symbol tags (#84747)

2024-03-11 Thread via cfe-commits

Author: Christian Kandeler
Date: 2024-03-11T13:16:58+01:00
New Revision: 9b2386e82dedafade233c8871637ee76da9ebe0e

URL: 
https://github.com/llvm/llvm-project/commit/9b2386e82dedafade233c8871637ee76da9ebe0e
DIFF: 
https://github.com/llvm/llvm-project/commit/9b2386e82dedafade233c8871637ee76da9ebe0e.diff

LOG: [clangd] Fix JSON conversion for symbol tags (#84747)

The wrong constructor of json::Value got called, making every tag an
array instead of a number.

Added: 


Modified: 
clang-tools-extra/clangd/Protocol.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index 8aa18bb0058abe..c6553e00dcae28 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, 
ReferenceParams &R,
 }
 
 llvm::json::Value toJSON(SymbolTag Tag) {
-  return llvm::json::Value{static_cast(Tag)};
+  return llvm::json::Value(static_cast(Tag));
 }
 
 llvm::json::Value toJSON(const CallHierarchyItem &I) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Fix JSON conversion for symbol tags (PR #84747)

2024-03-11 Thread Sam McCall via cfe-commits

sam-mccall wrote:

Thanks! (And sorry, that json::Value constructor is my fault too...)

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits

https://github.com/NagyDonat commented:

Seems to be a good change overall and I like that you implemented this with 
some nice helper classes. However, there is some code duplication that could be 
reduced (see inline comments).

Also, I feel that (especially after these extensions) this checker duplicates 
some logic that also appears in `PthreadLockChecker.cpp`. I didn't check the 
exact details but that checker is also modeling the locking and unlocking calls 
in order to report bad locking/unlocking order.

In theory it would be to ensure that we don't develop and maintain two similar 
but different solutions that both track lock handling code -- but 
PthreadLockChecker is 700 lines long and I understand that it would be 
difficult to unify it with this checker.

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits


@@ -20,48 +20,180 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+
+#include 
+#include 
+#include 
 
 using namespace clang;
 using namespace ento;
 
 namespace {
+
+struct CritSectionMarker {
+  const Expr *LockExpr{};
+  const MemRegion *LockReg{};
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+ID.Add(LockExpr);
+ID.Add(LockReg);
+  }
+
+  [[nodiscard]] constexpr bool
+  operator==(const CritSectionMarker &Other) const noexcept {
+return LockExpr == Other.LockExpr && LockReg == Other.LockReg;
+  }
+  [[nodiscard]] constexpr bool
+  operator!=(const CritSectionMarker &Other) const noexcept {
+return !(*this == Other);
+  }
+};
+
+class FirstArgMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+};
+
+class MemberMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call);
+  }
+  bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call);
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+};

NagyDonat wrote:

Would it be possible to reduce the code duplication between these by 
introducing a common ancestor class?

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits


@@ -20,48 +20,180 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+
+#include 
+#include 
+#include 
 
 using namespace clang;
 using namespace ento;
 
 namespace {
+
+struct CritSectionMarker {
+  const Expr *LockExpr{};
+  const MemRegion *LockReg{};
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+ID.Add(LockExpr);
+ID.Add(LockReg);
+  }
+
+  [[nodiscard]] constexpr bool
+  operator==(const CritSectionMarker &Other) const noexcept {
+return LockExpr == Other.LockExpr && LockReg == Other.LockReg;
+  }
+  [[nodiscard]] constexpr bool
+  operator!=(const CritSectionMarker &Other) const noexcept {
+return !(*this == Other);
+  }
+};
+
+class FirstArgMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+};
+
+class MemberMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call);
+  }
+  bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call);
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+};
+
+class RAIIMutexDescriptor {
+  mutable const IdentifierInfo *Guard{};
+  mutable bool IdentifierInfoInitialized{};
+  mutable llvm::SmallString<32> GuardName{};
+
+  void initIdentifierInfo(const CallEvent &Call) const {
+if (!IdentifierInfoInitialized) {
+  // In case of checking C code, or when the corresponding headers are not
+  // included, we might end up query the identifier table every time when
+  // this function is called instead of early returning it. To avoid this, 
a
+  // bool variable (IdentifierInfoInitialized) is used and the function 
will
+  // be run only once.
+  Guard = &Call.getCalleeAnalysisDeclContext()->getASTContext().Idents.get(
+  GuardName);
+  IdentifierInfoInitialized = true;
+}
+  }
+
+public:
+  RAIIMutexDescriptor(StringRef GuardName) : GuardName(GuardName) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+initIdentifierInfo(Call);
+const auto *Ctor = dyn_cast(&Call);
+if (!Ctor)
+  return false;
+auto *IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier();
+return IdentifierInfo == Guard;
+  }
+  [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const {
+initIdentifierInfo(Call);
+const auto *Dtor = dyn_cast(&Call);
+if (!Dtor)
+  return false;
+auto *IdentifierInfo =
+cast(Dtor->getDecl()->getParent())->getIdentifier();
+return IdentifierInfo == Guard;
+  }

NagyDonat wrote:

The methods `matchesLock()` and `matchesUnlock()` are a bit complex and almost 
identical, consider implementing them as calling 
`matchesImpl(Call)` and 
`matchesImpl(Call)` with a template function that contains 
the shared logic.

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits


@@ -70,73 +202,121 @@ class BlockInCriticalSectionChecker : public 
Checker {
 
 } // end anonymous namespace
 
-REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)
+REGISTER_LIST_WITH_PROGRAMSTATE(ActiveCritSections, CritSectionMarker)
 
-void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const {
-  if (!IdentifierInfoInitialized) {
-/* In case of checking C code, or when the corresponding headers are not
- * included, we might end up query the identifier table every time when 
this
- * function is called instead of early returning it. To avoid this, a bool
- * variable (IdentifierInfoInitialized) is used and the function will be 
run
- * only once. */
-IILockGuard  = &Ctx.Idents.get(ClassLockGuard);
-IIUniqueLock = &Ctx.Idents.get(ClassUniqueLock);
-IdentifierInfoInitialized = true;
-  }
-}
+namespace std {
+// Iterator traits for ImmutableList data structure
+// that enable the use of STL algorithms.
+// TODO: Move these to llvm::ImmutableList when overhauling immutable data
+// structures for proper iterator concept support.
+template <>
+struct iterator_traits<
+typename llvm::ImmutableList::iterator> {
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = CritSectionMarker;
+  using difference_type = std::ptrdiff_t;
+  using reference = CritSectionMarker &;
+  using pointer = CritSectionMarker *;
+};
+} // namespace std
 
-bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) 
const {
-  return matchesAny(Call, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn);
+std::optional
+BlockInCriticalSectionChecker::checkLock(const CallEvent &Call,
+ CheckerContext &C) const {
+  const auto *LockDescriptor =
+  llvm::find_if(MutexDescriptors, [&Call](auto &&LockFn) {
+return std::visit(
+[&Call](auto &&Descriptor) { return Descriptor.matchesLock(Call); 
},
+LockFn);
+  });
+  if (LockDescriptor != MutexDescriptors.end())
+return *LockDescriptor;
+  return std::nullopt;
 }
 
-bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) 
const {
-  if (const auto *Ctor = dyn_cast(&Call)) {
-auto IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier();
-if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock)
-  return true;
-  }
+void BlockInCriticalSectionChecker::handleLock(
+const MutexDescriptor &LockDescriptor, const CallEvent &Call,
+CheckerContext &C) const {
+  const auto *MutexRegion = std::visit(
+  [&Call](auto &&Descriptor) { return Descriptor.getLockRegion(Call); },
+  LockDescriptor);
+  if (!MutexRegion)
+return;
+
+  const auto MarkToAdd = CritSectionMarker{Call.getOriginExpr(), MutexRegion};
+  ProgramStateRef StateWithLockEvent =
+  C.getState()->add(MarkToAdd);
+  C.addTransition(StateWithLockEvent, createCritSectionNote(MarkToAdd, C));
+}
 
-  return matchesAny(Call, LockFn, PthreadLockFn, PthreadTryLockFn, MtxLock,
-MtxTimedLock, MtxTryLock);
+std::optional
+BlockInCriticalSectionChecker::checkUnlock(const CallEvent &Call,
+   CheckerContext &C) const {
+  const auto *UnlockDescriptor =
+  llvm::find_if(MutexDescriptors, [&Call](auto &&UnlockFn) {
+return std::visit(
+[&Call](auto &&Descriptor) {
+  return Descriptor.matchesUnlock(Call);
+},
+UnlockFn);
+  });
+  if (UnlockDescriptor != MutexDescriptors.end())
+return *UnlockDescriptor;
+  return std::nullopt;

NagyDonat wrote:

This is an almost exact duplicate of `checkLock()`. It would be better to unify 
them into a single function (e.g. `checkLockUnlock` that takes a boolean 
argument `IsLock` (and then also unify `matchesLock`/`matchesUnlock` into a 
single function that takes a boolean).

I know that boolean arguments can be a code smell, but in this particular case 
it would be a much better solution than this code duplication.

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


[clang] [clang][analyzer] Improve BlockInCriticalSectionsChecker (PR #80029)

2024-03-11 Thread via cfe-commits


@@ -20,48 +20,180 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+
+#include 
+#include 
+#include 
 
 using namespace clang;
 using namespace ento;
 
 namespace {
+
+struct CritSectionMarker {
+  const Expr *LockExpr{};
+  const MemRegion *LockReg{};
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+ID.Add(LockExpr);
+ID.Add(LockReg);
+  }
+
+  [[nodiscard]] constexpr bool
+  operator==(const CritSectionMarker &Other) const noexcept {
+return LockExpr == Other.LockExpr && LockReg == Other.LockReg;
+  }
+  [[nodiscard]] constexpr bool
+  operator!=(const CritSectionMarker &Other) const noexcept {
+return !(*this == Other);
+  }
+};
+
+class FirstArgMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call) && Call.getNumArgs() > 0;
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return Call.getArgSVal(0).getAsRegion();
+  }
+};
+
+class MemberMutexDescriptor {
+  CallDescription LockFn;
+  CallDescription UnlockFn;
+
+public:
+  MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
+  : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+return LockFn.matches(Call);
+  }
+  bool matchesUnlock(const CallEvent &Call) const {
+return UnlockFn.matches(Call);
+  }
+  [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+  [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const {
+return cast(Call).getCXXThisVal().getAsRegion();
+  }
+};
+
+class RAIIMutexDescriptor {
+  mutable const IdentifierInfo *Guard{};
+  mutable bool IdentifierInfoInitialized{};
+  mutable llvm::SmallString<32> GuardName{};
+
+  void initIdentifierInfo(const CallEvent &Call) const {
+if (!IdentifierInfoInitialized) {
+  // In case of checking C code, or when the corresponding headers are not
+  // included, we might end up query the identifier table every time when
+  // this function is called instead of early returning it. To avoid this, 
a
+  // bool variable (IdentifierInfoInitialized) is used and the function 
will
+  // be run only once.
+  Guard = &Call.getCalleeAnalysisDeclContext()->getASTContext().Idents.get(
+  GuardName);
+  IdentifierInfoInitialized = true;
+}
+  }
+
+public:
+  RAIIMutexDescriptor(StringRef GuardName) : GuardName(GuardName) {}
+  [[nodiscard]] bool matchesLock(const CallEvent &Call) const {
+initIdentifierInfo(Call);
+const auto *Ctor = dyn_cast(&Call);
+if (!Ctor)
+  return false;
+auto *IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier();
+return IdentifierInfo == Guard;
+  }
+  [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const {
+initIdentifierInfo(Call);
+const auto *Dtor = dyn_cast(&Call);
+if (!Dtor)
+  return false;
+auto *IdentifierInfo =
+cast(Dtor->getDecl()->getParent())->getIdentifier();

NagyDonat wrote:

Why do you need a cast to `CXXRecordDecl` here if it isn't needed for the 
constructor?

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


[clang] aec9283 - [clang-repl] Refactor locking of runtime PTU stack (NFC) (#84176)

2024-03-11 Thread via cfe-commits

Author: Stefan Gränitz
Date: 2024-03-11T13:39:23+01:00
New Revision: aec92830b79a8c49cdce0d592627d5f18bb6370b

URL: 
https://github.com/llvm/llvm-project/commit/aec92830b79a8c49cdce0d592627d5f18bb6370b
DIFF: 
https://github.com/llvm/llvm-project/commit/aec92830b79a8c49cdce0d592627d5f18bb6370b.diff

LOG: [clang-repl] Refactor locking of runtime PTU stack (NFC) (#84176)

The Interpreter locks PTUs that originate from implicit runtime code and
initialization to prevent users from undoing them accidentally.

The previous implementation seemed hacky, because it required the reader
to be familiar with the internal workings of the PTU stack. The concept
itself is a pragmatic solution and not very surprising. This patch
introduces a function for it and adds a comment.

Added: 


Modified: 
clang/include/clang/Interpreter/Interpreter.h
clang/lib/Interpreter/Interpreter.cpp

Removed: 




diff  --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index d972d960dcb7cd..469ce1fd75bf84 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -169,6 +169,7 @@ class Interpreter {
 
 private:
   size_t getEffectivePTUSize() const;
+  void markUserCodeStart();
 
   llvm::DenseMap Dtors;
 

diff  --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 3485da8196683a..e293fefb524963 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -280,15 +280,14 @@ Interpreter::create(std::unique_ptr CI) 
{
   if (Err)
 return std::move(Err);
 
+  // Add runtime code and set a marker to hide it from user code. Undo will not
+  // go through that.
   auto PTU = Interp->Parse(Runtimes);
   if (!PTU)
 return PTU.takeError();
+  Interp->markUserCodeStart();
 
   Interp->ValuePrintingInfo.resize(4);
-  // FIXME: This is a ugly hack. Undo command checks its availability by 
looking
-  // at the size of the PTU list. However we have parsed something in the
-  // beginning of the REPL so we have to mark them as 'Irrevocable'.
-  Interp->InitPTUSize = Interp->IncrParser->getPTUs().size();
   return std::move(Interp);
 }
 
@@ -345,6 +344,11 @@ const ASTContext &Interpreter::getASTContext() const {
   return getCompilerInstance()->getASTContext();
 }
 
+void Interpreter::markUserCodeStart() {
+  assert(!InitPTUSize && "We only do this once");
+  InitPTUSize = IncrParser->getPTUs().size();
+}
+
 size_t Interpreter::getEffectivePTUSize() const {
   std::list &PTUs = IncrParser->getPTUs();
   assert(PTUs.size() >= InitPTUSize && "empty PTU list?");



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-repl] Refactor locking of runtime PTU stack (NFC) (PR #84176)

2024-03-11 Thread Stefan Gränitz via cfe-commits

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


[clang] [compiler-rt] [clang][UBSan] Add implicit conversion check for bitfields (PR #75481)

2024-03-11 Thread Axel Lundberg via cfe-commits


@@ -555,13 +555,11 @@ static void 
handleImplicitConversion(ImplicitConversionData *Data,
  ReportOptions Opts, ValueHandle Src,
  ValueHandle Dst) {
   SourceLocation Loc = Data->Loc.acquire();
-  ErrorType ET = ErrorType::GenericUB;
-
   const TypeDescriptor &SrcTy = Data->FromType;
   const TypeDescriptor &DstTy = Data->ToType;
-
   bool SrcSigned = SrcTy.isSignedIntegerTy();
   bool DstSigned = DstTy.isSignedIntegerTy();
+  ErrorType ET = ErrorType::GenericUB;

Zonotora wrote:

I have only moved this line... I think changing the error type is for a future 
PR as you comment further down.

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


[clang] [compiler-rt] [clang][UBSan] Add implicit conversion check for bitfields (PR #75481)

2024-03-11 Thread Axel Lundberg via cfe-commits

Zonotora wrote:

@zygoloid Thanks for your feedback! Fixed all comments except the last one. I 
totally agree with you about the distinction of UB checks, and that should be 
part of a different future PR! 

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


[clang] Add bit-precise overloads for builtin operators (PR #84755)

2024-03-11 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman created 
https://github.com/llvm/llvm-project/pull/84755

We previously were not adding them to the candidate set and so use of a 
bit-precise integer as a class member could lead to ambiguous overload sets.

Fixes https://github.com/llvm/llvm-project/issues/82998

>From 1f57de0e2e11a4bd834871e7d033ec53c43dc42e Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Mon, 11 Mar 2024 08:41:37 -0400
Subject: [PATCH] Add bit-precise overloads for builtin operators

We previously were not adding them to the candidate set and so use of a
bit-precise integer as a class member could lead to ambiguous overload
sets.

Fixes #82998
---
 clang/docs/ReleaseNotes.rst|  3 ++
 clang/lib/Sema/SemaOverload.cpp| 23 ++
 clang/test/SemaCXX/overload-bitint.cpp | 42 ++
 3 files changed, 68 insertions(+)
 create mode 100644 clang/test/SemaCXX/overload-bitint.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0ee2801766a9cc..ab95d74d4356f5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -254,6 +254,9 @@ Bug Fixes in This Version
   operator.
   Fixes (#GH83267).
 
+- Clang now correctly generates overloads for bit-precise integer types for
+  builtin operators in C++. Fixes #GH82998.
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index b0c693f078efe2..675f6f9ebcda5f 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8516,6 +8516,9 @@ class BuiltinCandidateTypeSet  {
   /// candidates.
   TypeSet MatrixTypes;
 
+  /// The set of _BitInt types that will be used in the built-in candidates.
+  TypeSet BitIntTypes;
+
   /// A flag indicating non-record types are viable candidates
   bool HasNonRecordTypes;
 
@@ -8564,6 +8567,7 @@ class BuiltinCandidateTypeSet  {
   }
   llvm::iterator_range vector_types() { return VectorTypes; }
   llvm::iterator_range matrix_types() { return MatrixTypes; }
+  llvm::iterator_range bitint_types() { return BitIntTypes; }
 
   bool containsMatrixType(QualType Ty) const { return MatrixTypes.count(Ty); }
   bool hasNonRecordTypes() { return HasNonRecordTypes; }
@@ -8735,6 +8739,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType 
Ty,
   } else if (Ty->isEnumeralType()) {
 HasArithmeticOrEnumeralTypes = true;
 EnumerationTypes.insert(Ty);
+  } else if (Ty->isBitIntType()) {
+HasArithmeticOrEnumeralTypes = true;
+BitIntTypes.insert(Ty);
   } else if (Ty->isVectorType()) {
 // We treat vector types as arithmetic types in many contexts as an
 // extension.
@@ -8955,6 +8962,22 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// _BitInt overloads are a bit special. We don't want to add candidates
+/// for the entire family of _BitInt types, so instead we only add
+/// candidates for the unique, unqualified _BitInt types present in the
+/// candidate type set. The candidate set already handled ensuring the type
+/// is unqualified and canonical, but because we're adding from N different
+/// sets, we need to do some extra work to unique things. Copy the
+/// candidates into a unique set, then copy from that set into the list of
+/// arithmetic types.
+llvm::SmallSetVector BitIntCandidates;
+llvm::for_each(CandidateTypes, [&BitIntCandidates](
+   BuiltinCandidateTypeSet &Candidate) {
+  for (QualType BitTy : Candidate.bitint_types())
+BitIntCandidates.insert(CanQualType::CreateUnsafe(BitTy));
+});
+llvm::copy(BitIntCandidates, std::back_inserter(ArithmeticTypes));
 LastPromotedIntegralType = ArithmeticTypes.size();
 LastPromotedArithmeticType = ArithmeticTypes.size();
 // End of promoted types.
diff --git a/clang/test/SemaCXX/overload-bitint.cpp 
b/clang/test/SemaCXX/overload-bitint.cpp
new file mode 100644
index 00..b834a3b01fede6
--- /dev/null
+++ b/clang/test/SemaCXX/overload-bitint.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+// expected-no-diagnostics
+
+#include "Inputs/std-compare.h"
+
+struct S {
+  _BitInt(12) a;
+
+  constexpr operator _BitInt(12)() const { return a; }
+};
+
+// None of these used to compile because we weren't adding _BitInt types to the
+// overload set for builtin operators. See GH82998.
+static_assert(S{10} < 11);
+static_assert(S{10} <= 11);
+static_assert(S{12} > 11);
+static_assert(S{12} >= 11);
+static_assert(S{10} == 10);
+static_assert((S{10} <=> 10) == 0);
+static_assert(S{10} != 11);
+static_assert(S{10} + 0 == 10);
+static_assert(S{10} - 0 == 10);
+static_assert(S{10} * 1 == 10);
+static_assert(S{10} / 1 == 10);
+static_assert(S{10} % 1 == 0);
+static_assert(S{10} << 0 == 10

[clang] Add bit-precise overloads for builtin operators (PR #84755)

2024-03-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)


Changes

We previously were not adding them to the candidate set and so use of a 
bit-precise integer as a class member could lead to ambiguous overload sets.

Fixes https://github.com/llvm/llvm-project/issues/82998

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+23) 
- (added) clang/test/SemaCXX/overload-bitint.cpp (+42) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bce27dc8c4a996..5b3a5b6c9bf23e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -262,6 +262,9 @@ Bug Fixes in This Version
   operator.
   Fixes (#GH83267).
 
+- Clang now correctly generates overloads for bit-precise integer types for
+  builtin operators in C++. Fixes #GH82998.
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index b0c693f078efe2..675f6f9ebcda5f 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8516,6 +8516,9 @@ class BuiltinCandidateTypeSet  {
   /// candidates.
   TypeSet MatrixTypes;
 
+  /// The set of _BitInt types that will be used in the built-in candidates.
+  TypeSet BitIntTypes;
+
   /// A flag indicating non-record types are viable candidates
   bool HasNonRecordTypes;
 
@@ -8564,6 +8567,7 @@ class BuiltinCandidateTypeSet  {
   }
   llvm::iterator_range vector_types() { return VectorTypes; }
   llvm::iterator_range matrix_types() { return MatrixTypes; }
+  llvm::iterator_range bitint_types() { return BitIntTypes; }
 
   bool containsMatrixType(QualType Ty) const { return MatrixTypes.count(Ty); }
   bool hasNonRecordTypes() { return HasNonRecordTypes; }
@@ -8735,6 +8739,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType 
Ty,
   } else if (Ty->isEnumeralType()) {
 HasArithmeticOrEnumeralTypes = true;
 EnumerationTypes.insert(Ty);
+  } else if (Ty->isBitIntType()) {
+HasArithmeticOrEnumeralTypes = true;
+BitIntTypes.insert(Ty);
   } else if (Ty->isVectorType()) {
 // We treat vector types as arithmetic types in many contexts as an
 // extension.
@@ -8955,6 +8962,22 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// _BitInt overloads are a bit special. We don't want to add candidates
+/// for the entire family of _BitInt types, so instead we only add
+/// candidates for the unique, unqualified _BitInt types present in the
+/// candidate type set. The candidate set already handled ensuring the type
+/// is unqualified and canonical, but because we're adding from N different
+/// sets, we need to do some extra work to unique things. Copy the
+/// candidates into a unique set, then copy from that set into the list of
+/// arithmetic types.
+llvm::SmallSetVector BitIntCandidates;
+llvm::for_each(CandidateTypes, [&BitIntCandidates](
+   BuiltinCandidateTypeSet &Candidate) {
+  for (QualType BitTy : Candidate.bitint_types())
+BitIntCandidates.insert(CanQualType::CreateUnsafe(BitTy));
+});
+llvm::copy(BitIntCandidates, std::back_inserter(ArithmeticTypes));
 LastPromotedIntegralType = ArithmeticTypes.size();
 LastPromotedArithmeticType = ArithmeticTypes.size();
 // End of promoted types.
diff --git a/clang/test/SemaCXX/overload-bitint.cpp 
b/clang/test/SemaCXX/overload-bitint.cpp
new file mode 100644
index 00..b834a3b01fede6
--- /dev/null
+++ b/clang/test/SemaCXX/overload-bitint.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+// expected-no-diagnostics
+
+#include "Inputs/std-compare.h"
+
+struct S {
+  _BitInt(12) a;
+
+  constexpr operator _BitInt(12)() const { return a; }
+};
+
+// None of these used to compile because we weren't adding _BitInt types to the
+// overload set for builtin operators. See GH82998.
+static_assert(S{10} < 11);
+static_assert(S{10} <= 11);
+static_assert(S{12} > 11);
+static_assert(S{12} >= 11);
+static_assert(S{10} == 10);
+static_assert((S{10} <=> 10) == 0);
+static_assert(S{10} != 11);
+static_assert(S{10} + 0 == 10);
+static_assert(S{10} - 0 == 10);
+static_assert(S{10} * 1 == 10);
+static_assert(S{10} / 1 == 10);
+static_assert(S{10} % 1 == 0);
+static_assert(S{10} << 0 == 10);
+static_assert(S{10} >> 0 == 10);
+static_assert((S{10} | 0) == 10);
+static_assert((S{10} & 10) == 10);
+static_assert((S{10} ^ 0) == 10);
+static_assert(-S{10} == -10);
+static_assert(+S{10} == +10);
+static_assert(~S{10} == ~10);
+
+struct A {
+  _BitInt(12) a;
+
+  bool operator==(const A&) const = default;
+  bool operator!=(const A&) const = default;
+  std::str

[clang] [analyzer] Turn NodeBuilderContext into a class (PR #84638)

2024-03-11 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Turn NodeBuilderContext into a class (PR #84638)

2024-03-11 Thread Balazs Benics via cfe-commits

https://github.com/steakhal commented:

Alright. So we can simply mark all the members private. I was surprised a bit.
LGTM, but remove the TODO comment you fix.

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


[clang] [analyzer] Turn NodeBuilderContext into a class (PR #84638)

2024-03-11 Thread Balazs Benics via cfe-commits


@@ -194,11 +194,12 @@ class CoreEngine {
 };
 
 // TODO: Turn into a class.

steakhal wrote:

Remove this TODO, as its completed.

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


[clang] [analyzer] Mention possibility of underflow in array overflow errors (PR #84201)

2024-03-11 Thread Balazs Benics via cfe-commits
=?utf-8?q?Don=C3=A1t?= Nagy ,NagyDonat
 
Message-ID:
In-Reply-To: 


https://github.com/steakhal approved this pull request.

I scrolled over, and it looks harmless, so LGTM.

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-11 Thread Balazs Benics via cfe-commits
Alejandro =?utf-8?q?Álvarez_Ayllón?=,
Alejandro =?utf-8?q?Álvarez_Ayllón?=,
Alejandro =?utf-8?q?Álvarez_Ayllón?=,
Alejandro =?utf-8?q?Álvarez_Ayllón?=,
Alejandro =?utf-8?q?Álvarez_Ayllón?=,
Alejandro =?utf-8?q?Álvarez_Ayllón?Message-ID:
In-Reply-To: 


steakhal wrote:

> I want to avoid that some functions have null pointer checks in 
> `StreamChecker`, some not. If this change is merged then it would be good to 
> add null pointer checks to other functions like `fread` and `fwrite`. (Until 
> now only the NULL stream pointer was checked.)

I can really think of having these checks at both checkers, so that both 
parties are sort of happy - except for of course having this precondition 
checked at both places. But to me, the question is really as follow: is it 
better with this, or not?
I'm also open for suggestions for resolving this conflict, so let me know if 
you have ideas.

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


[clang] [RemoveDIs] Update Clang front end to handle DbgRecords (PR #84756)

2024-03-11 Thread Orlando Cazalet-Hyams via cfe-commits

https://github.com/OCHyams created 
https://github.com/llvm/llvm-project/pull/84756

This patch fixes problems that pop up when clang emits DbgRecords instead of 
debug intrinsics.

Note: this doesn't mean clang is emitting DbgRecords yet, because the modules 
it creates are still always in the old debug mode. That will come in a future 
patch.



>From 8b37020a48b8145ad9d7deb288b9f8a3ee3a9a9b Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams 
Date: Sat, 9 Mar 2024 13:10:05 +
Subject: [PATCH 1/2] clang: insertbefore non-debug for removeDIs stability

fixes debug-info-blocks.m in both modes
---
 clang/lib/CodeGen/CGBlocks.cpp | 5 -
 clang/test/CodeGenObjC/debug-info-blocks.m | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 0cbace7b7f7bbd..768b786c6426df 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1540,7 +1540,10 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction(
   llvm::BasicBlock *resume = Builder.GetInsertBlock();
 
   // Go back to the entry.
-  ++entry_ptr;
+  if (entry_ptr->getNextNonDebugInstruction())
+entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();
+  else 
+entry_ptr = entry->end();
   Builder.SetInsertPoint(entry, entry_ptr);
 
   // Emit debug information for all the DeclRefExprs.
diff --git a/clang/test/CodeGenObjC/debug-info-blocks.m 
b/clang/test/CodeGenObjC/debug-info-blocks.m
index 14b29f222fbe8e..59171da016da1e 100644
--- a/clang/test/CodeGenObjC/debug-info-blocks.m
+++ b/clang/test/CodeGenObjC/debug-info-blocks.m
@@ -5,8 +5,8 @@
 
 // CHECK: define {{.*}}_block_invoke
 // CHECK: store ptr %.block_descriptor, ptr %[[ALLOCA:block.addr]], align
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 // CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %d, metadata 
![[D:[0-9]+]], metadata !{{.*}})
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 
 // Test that we do emit scope info for the helper functions, and that the
 // parameters to these functions are marked as artificial (so the debugger

>From efabe4b06f38aaf3aed8cf02c97f566652ba5f15 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams 
Date: Sat, 9 Mar 2024 13:40:30 +
Subject: [PATCH 2/2] openmp update DbgRecords

Fixed OpenMP/debug_task_shared.c
---
 clang/lib/CodeGen/CGStmtOpenMP.cpp | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 3fbd2e03eb61df..5c6a3b8e001730 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4746,10 +4746,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
 (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,
 CGF.Builder, false);
-  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
   // Get the call dbg.declare instruction we just created and update
   // its DIExpression to add offset to base address.
-  if (auto DDI = dyn_cast(&Last)) {
+  auto UpdateExpr = [](llvm::LLVMContext &Ctx, auto *DDI,
+   unsigned Offset) {
 SmallVector Ops;
 // Add offset to the base address if non zero.
 if (Offset) {
@@ -4757,9 +4757,21 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   Ops.push_back(Offset);
 }
 Ops.push_back(llvm::dwarf::DW_OP_deref);
-auto &Ctx = DDI->getContext();
-llvm::DIExpression *DIExpr = llvm::DIExpression::get(Ctx, Ops);
-Last.setOperand(2, llvm::MetadataAsValue::get(Ctx, DIExpr));
+DDI->setExpression(llvm::DIExpression::get(Ctx, Ops));
+  };
+  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
+  if (auto DDI = dyn_cast(&Last))
+UpdateExpr(DDI->getContext(), DDI, Offset);
+  // If we're emitting using the new debug info format into a block
+  // without a terminator, the record will be "trailing".
+  assert(!Last.isTerminator() && "unexpected terminator");
+  if (auto *Marker =
+  CGF.Builder.GetInsertBlock()->getTrailingDPValues()) {
+for (llvm::DPValue &DPV : llvm::reverse(
+ llvm::DPValue::filter(Marker->getDbgValueRange( {
+  UpdateExpr(Last.getContext(), &DPV, Offset);
+  break;
+}
   }
 }
   }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RemoveDIs] Update Clang front end to handle DbgRecords (PR #84756)

2024-03-11 Thread Orlando Cazalet-Hyams via cfe-commits

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


[clang] [RemoveDIs] Update Clang front end to handle DbgRecords (PR #84756)

2024-03-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Orlando Cazalet-Hyams (OCHyams)


Changes

This patch fixes problems that pop up when clang emits DbgRecords instead of 
debug intrinsics.

Note: this doesn't mean clang is emitting DbgRecords yet, because the modules 
it creates are still always in the old debug mode. That will come in a future 
patch.

Depends on #84739 


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


3 Files Affected:

- (modified) clang/lib/CodeGen/CGBlocks.cpp (+4-1) 
- (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+17-5) 
- (modified) clang/test/CodeGenObjC/debug-info-blocks.m (+1-1) 


``diff
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 0cbace7b7f7bbd..768b786c6426df 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1540,7 +1540,10 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction(
   llvm::BasicBlock *resume = Builder.GetInsertBlock();
 
   // Go back to the entry.
-  ++entry_ptr;
+  if (entry_ptr->getNextNonDebugInstruction())
+entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();
+  else 
+entry_ptr = entry->end();
   Builder.SetInsertPoint(entry, entry_ptr);
 
   // Emit debug information for all the DeclRefExprs.
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 3fbd2e03eb61df..5c6a3b8e001730 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4746,10 +4746,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
 (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,
 CGF.Builder, false);
-  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
   // Get the call dbg.declare instruction we just created and update
   // its DIExpression to add offset to base address.
-  if (auto DDI = dyn_cast(&Last)) {
+  auto UpdateExpr = [](llvm::LLVMContext &Ctx, auto *DDI,
+   unsigned Offset) {
 SmallVector Ops;
 // Add offset to the base address if non zero.
 if (Offset) {
@@ -4757,9 +4757,21 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   Ops.push_back(Offset);
 }
 Ops.push_back(llvm::dwarf::DW_OP_deref);
-auto &Ctx = DDI->getContext();
-llvm::DIExpression *DIExpr = llvm::DIExpression::get(Ctx, Ops);
-Last.setOperand(2, llvm::MetadataAsValue::get(Ctx, DIExpr));
+DDI->setExpression(llvm::DIExpression::get(Ctx, Ops));
+  };
+  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
+  if (auto DDI = dyn_cast(&Last))
+UpdateExpr(DDI->getContext(), DDI, Offset);
+  // If we're emitting using the new debug info format into a block
+  // without a terminator, the record will be "trailing".
+  assert(!Last.isTerminator() && "unexpected terminator");
+  if (auto *Marker =
+  CGF.Builder.GetInsertBlock()->getTrailingDPValues()) {
+for (llvm::DPValue &DPV : llvm::reverse(
+ llvm::DPValue::filter(Marker->getDbgValueRange( {
+  UpdateExpr(Last.getContext(), &DPV, Offset);
+  break;
+}
   }
 }
   }
diff --git a/clang/test/CodeGenObjC/debug-info-blocks.m 
b/clang/test/CodeGenObjC/debug-info-blocks.m
index 14b29f222fbe8e..59171da016da1e 100644
--- a/clang/test/CodeGenObjC/debug-info-blocks.m
+++ b/clang/test/CodeGenObjC/debug-info-blocks.m
@@ -5,8 +5,8 @@
 
 // CHECK: define {{.*}}_block_invoke
 // CHECK: store ptr %.block_descriptor, ptr %[[ALLOCA:block.addr]], align
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 // CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %d, metadata 
![[D:[0-9]+]], metadata !{{.*}})
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 
 // Test that we do emit scope info for the helper functions, and that the
 // parameters to these functions are marked as artificial (so the debugger

``




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


[clang] [RemoveDIs] Update Clang front end to handle DbgRecords (PR #84756)

2024-03-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Orlando Cazalet-Hyams (OCHyams)


Changes

This patch fixes problems that pop up when clang emits DbgRecords instead of 
debug intrinsics.

Note: this doesn't mean clang is emitting DbgRecords yet, because the modules 
it creates are still always in the old debug mode. That will come in a future 
patch.

Depends on #84739 


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


3 Files Affected:

- (modified) clang/lib/CodeGen/CGBlocks.cpp (+4-1) 
- (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+17-5) 
- (modified) clang/test/CodeGenObjC/debug-info-blocks.m (+1-1) 


``diff
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 0cbace7b7f7bbd..768b786c6426df 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1540,7 +1540,10 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction(
   llvm::BasicBlock *resume = Builder.GetInsertBlock();
 
   // Go back to the entry.
-  ++entry_ptr;
+  if (entry_ptr->getNextNonDebugInstruction())
+entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();
+  else 
+entry_ptr = entry->end();
   Builder.SetInsertPoint(entry, entry_ptr);
 
   // Emit debug information for all the DeclRefExprs.
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 3fbd2e03eb61df..5c6a3b8e001730 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4746,10 +4746,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
 (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,
 CGF.Builder, false);
-  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
   // Get the call dbg.declare instruction we just created and update
   // its DIExpression to add offset to base address.
-  if (auto DDI = dyn_cast(&Last)) {
+  auto UpdateExpr = [](llvm::LLVMContext &Ctx, auto *DDI,
+   unsigned Offset) {
 SmallVector Ops;
 // Add offset to the base address if non zero.
 if (Offset) {
@@ -4757,9 +4757,21 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
   Ops.push_back(Offset);
 }
 Ops.push_back(llvm::dwarf::DW_OP_deref);
-auto &Ctx = DDI->getContext();
-llvm::DIExpression *DIExpr = llvm::DIExpression::get(Ctx, Ops);
-Last.setOperand(2, llvm::MetadataAsValue::get(Ctx, DIExpr));
+DDI->setExpression(llvm::DIExpression::get(Ctx, Ops));
+  };
+  llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
+  if (auto DDI = dyn_cast(&Last))
+UpdateExpr(DDI->getContext(), DDI, Offset);
+  // If we're emitting using the new debug info format into a block
+  // without a terminator, the record will be "trailing".
+  assert(!Last.isTerminator() && "unexpected terminator");
+  if (auto *Marker =
+  CGF.Builder.GetInsertBlock()->getTrailingDPValues()) {
+for (llvm::DPValue &DPV : llvm::reverse(
+ llvm::DPValue::filter(Marker->getDbgValueRange( {
+  UpdateExpr(Last.getContext(), &DPV, Offset);
+  break;
+}
   }
 }
   }
diff --git a/clang/test/CodeGenObjC/debug-info-blocks.m 
b/clang/test/CodeGenObjC/debug-info-blocks.m
index 14b29f222fbe8e..59171da016da1e 100644
--- a/clang/test/CodeGenObjC/debug-info-blocks.m
+++ b/clang/test/CodeGenObjC/debug-info-blocks.m
@@ -5,8 +5,8 @@
 
 // CHECK: define {{.*}}_block_invoke
 // CHECK: store ptr %.block_descriptor, ptr %[[ALLOCA:block.addr]], align
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 // CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %d, metadata 
![[D:[0-9]+]], metadata !{{.*}})
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata 
![[SELF:[0-9]+]], metadata !{{.*}})
 
 // Test that we do emit scope info for the helper functions, and that the
 // parameters to these functions are marked as artificial (so the debugger

``




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


[clang] [RemoveDIs] Update Clang front end to handle DbgRecords (PR #84756)

2024-03-11 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff e77f5fe889909df3508fd929f2636a0ac211877a 
efabe4b06f38aaf3aed8cf02c97f566652ba5f15 -- clang/lib/CodeGen/CGBlocks.cpp 
clang/lib/CodeGen/CGStmtOpenMP.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 768b786c64..ad0b50d799 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1542,7 +1542,7 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction(
   // Go back to the entry.
   if (entry_ptr->getNextNonDebugInstruction())
 entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();
-  else 
+  else
 entry_ptr = entry->end();
   Builder.SetInsertPoint(entry, entry_ptr);
 

``




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


[clang] [llvm] [analyzer] Mention possibility of underflow in array overflow errors (PR #84201)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,NagyDonat
 ,Balazs Benics 
Message-ID:
In-Reply-To: 


https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/84201

>From 74c7c04cb456c0a058ca36a2ca4ffa4d70d576e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Wed, 6 Mar 2024 18:09:02 +0100
Subject: [PATCH 1/4] [analyzer] Mention possibility of underflow in array
 overflow errors

The checker alpha.security.ArrayBoundV2 performs bounds checking in two
steps: first it checks for underflow, and if it isn't guaranteed then it
assumes that there is no underflow. After this, it checks for overflow,
and if it's guaranteed or the index is tainted then it reports it.

This meant that in situations where overflow and underflow are both
possible (but the index is either tainted or guaranteed to be invalid),
the checker was reporting an overflow error.

This commit modifies the messages printed in these cases to mention the
possibility of an underflow.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 37 +++-
 .../test/Analysis/out-of-bounds-diagnostics.c | 56 ++-
 .../test/Analysis/taint-diagnostic-visitor.c  |  2 +-
 3 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index 29eb932584027d..664d26b00a3cab 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -83,6 +83,8 @@ class StateUpdateReporter {
 AssumedUpperBound = UpperBoundVal;
   }
 
+  bool assumedNonNegative() { return AssumedNonNegative; }
+
   const NoteTag *createNoteTag(CheckerContext &C) const;
 
 private:
@@ -402,7 +404,8 @@ static bool tryDividePair(std::optional &Val1,
 }
 
 static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region,
-   NonLoc Offset, NonLoc Extent, SVal Location) {
+   NonLoc Offset, NonLoc Extent, SVal Location,
+   bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   const auto *EReg = Location.getAsRegion()->getAs();
   assert(EReg && "this checker only handles element access");
@@ -414,6 +417,7 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity();
 
   bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize);
+  const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index";
 
   SmallString<256> Buf;
   llvm::raw_svector_ostream Out(Buf);
@@ -421,10 +425,12 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   if (!ExtentN && !UseByteOffsets)
 Out << "'" << ElemType.getAsString() << "' element in ";
   Out << RegName << " at ";
-  if (OffsetN) {
-Out << (UseByteOffsets ? "byte offset " : "index ") << *OffsetN;
+  if (AssumedNonNegative) {
+Out << "a negative or overflowing " << OffsetOrIndex;
+  } else if (OffsetN) {
+Out << OffsetOrIndex << " " << *OffsetN;
   } else {
-Out << "an overflowing " << (UseByteOffsets ? "byte offset" : "index");
+Out << "an overflowing " << OffsetOrIndex;
   }
   if (ExtentN) {
 Out << ", while it holds only ";
@@ -441,17 +447,19 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   Out << "s";
   }
 
-  return {
-  formatv("Out of bound access to memory after the end of {0}", RegName),
-  std::string(Buf)};
+  return {formatv("Out of bound access to memory {0} {1}",
+  AssumedNonNegative ? "around" : "after the end of", RegName),
+  std::string(Buf)};
 }
 
-static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName) {
+static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName,
+ bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   return {formatv("Potential out of bound access to {0} with tainted {1}",
   RegName, OffsetName),
-  formatv("Access of {0} with a tainted {1} that may be too large",
-  RegName, OffsetName)};
+  formatv("Access of {0} with a tainted {1} that may be {2}too large",
+  RegName, OffsetName,
+  AssumedNonNegative ? "negative or " : "")};
 }
 
 const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const {
@@ -603,6 +611,8 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, 
CheckerContext &C) const {
 auto [WithinUpperBound, ExceedsUpperBound] =
 compareValueToThreshold(State, ByteOffset, *KnownSize, SVB);
 
+bool AssumedNonNegative = SUR.assumedNonNegative();
+
 if (ExceedsUpperBound) {
   // The offset may be invalid (>= Size)...
   if (!WithinUpperBound) {
@@ -615,8 +625,9 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, 
CheckerContext &C) c

[clang] Clang repl implicit executor create (PR #84758)

2024-03-11 Thread Stefan Gränitz via cfe-commits

https://github.com/weliveindetail created 
https://github.com/llvm/llvm-project/pull/84758

Until now the IncrExecutor is created lazily on the first execution request. In 
order to process the PTUs that come from initialization, we have to do it 
upfront implicitly.

From 2f7b523472543a92a97701880f8cd3c928061f53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= 
Date: Sun, 10 Mar 2024 18:17:48 +0100
Subject: [PATCH 1/2] [clang-repl] Set up executor implicitly to account for
 init PTUs

---
 clang/lib/Interpreter/Interpreter.cpp | 30 +++
 clang/test/Interpreter/execute.cpp|  4 ++--
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e293fefb524963..5e1161ca472b36 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -229,12 +229,30 @@ IncrementalCompilerBuilder::CreateCudaHost() {
 }
 
 Interpreter::Interpreter(std::unique_ptr CI,
- llvm::Error &Err) {
-  llvm::ErrorAsOutParameter EAO(&Err);
+ llvm::Error &ErrOut) {
+  llvm::ErrorAsOutParameter EAO(&ErrOut);
   auto LLVMCtx = std::make_unique();
   TSCtx = std::make_unique(std::move(LLVMCtx));
-  IncrParser = std::make_unique(*this, std::move(CI),
-   *TSCtx->getContext(), Err);
+  IncrParser = std::make_unique(
+  *this, std::move(CI), *TSCtx->getContext(), ErrOut);
+  if (ErrOut)
+return;
+
+  // Not all frontends support code-generation, e.g. ast-dump actions don't
+  if (IncrParser->getCodeGen()) {
+if (llvm::Error Err = CreateExecutor()) {
+  ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
+  return;
+}
+
+// Process the PTUs that came from initialization. For example -include 
will
+// give us a header that's processed at initialization of the preprocessor.
+for (PartialTranslationUnit &PTU : IncrParser->getPTUs())
+  if (llvm::Error Err = Execute(PTU)) {
+ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
+return;
+  }
+  }
 }
 
 Interpreter::~Interpreter() {
@@ -375,6 +393,10 @@ Interpreter::Parse(llvm::StringRef Code) {
 llvm::Error Interpreter::CreateExecutor() {
   const clang::TargetInfo &TI =
   getCompilerInstance()->getASTContext().getTargetInfo();
+  if (!IncrParser->getCodeGen())
+return llvm::make_error("Operation failed. "
+   "No code generator available",
+   std::error_code());
   llvm::Error Err = llvm::Error::success();
   auto Executor = std::make_unique(*TSCtx, Err, TI);
   if (!Err)
diff --git a/clang/test/Interpreter/execute.cpp 
b/clang/test/Interpreter/execute.cpp
index 6e73ed3927e815..534a54ed94fba2 100644
--- a/clang/test/Interpreter/execute.cpp
+++ b/clang/test/Interpreter/execute.cpp
@@ -7,6 +7,8 @@
 
 // RUN: cat %s | clang-repl | FileCheck %s
 // RUN: cat %s | clang-repl -Xcc -O2 | FileCheck %s
+// RUN: clang-repl -Xcc -include -Xcc %s | FileCheck %s
+// RUN: clang-repl -Xcc -fsyntax-only -Xcc -include -Xcc %s
 extern "C" int printf(const char *, ...);
 int i = 42;
 auto r1 = printf("i = %d\n", i);
@@ -19,5 +21,3 @@ auto r2 = printf("S[f=%f, m=0x%llx]\n", s.f, 
reinterpret_cast
Date: Mon, 11 Mar 2024 14:10:58 +0100
Subject: [PATCH 2/2] [tmp] Add crash note

---
 clang/test/Interpreter/inline-virtual.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Interpreter/inline-virtual.cpp 
b/clang/test/Interpreter/inline-virtual.cpp
index 79ab8ed337ffea..d862b3354f61fe 100644
--- a/clang/test/Interpreter/inline-virtual.cpp
+++ b/clang/test/Interpreter/inline-virtual.cpp
@@ -14,7 +14,7 @@ struct A { int a; A(int a) : a(a) {} virtual ~A(); };
 // PartialTranslationUnit.
 inline A::~A() { printf("~A(%d)\n", a); }
 
-// Create one instance with new and delete it.
+// Create one instance with new and delete it. We crash here now:
 A *a1 = new A(1);
 delete a1;
 // CHECK: ~A(1)

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Clang repl implicit executor create (PR #84758)

2024-03-11 Thread via cfe-commits
Stefan =?utf-8?q?Gränitz?= 
Message-ID:
In-Reply-To: 


llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Stefan Gränitz (weliveindetail)


Changes

Until now the IncrExecutor is created lazily on the first execution request. In 
order to process the PTUs that come from initialization, we have to do it 
upfront implicitly.

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


3 Files Affected:

- (modified) clang/lib/Interpreter/Interpreter.cpp (+26-4) 
- (modified) clang/test/Interpreter/execute.cpp (+2-2) 
- (modified) clang/test/Interpreter/inline-virtual.cpp (+1-1) 


``diff
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e293fefb524963..5e1161ca472b36 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -229,12 +229,30 @@ IncrementalCompilerBuilder::CreateCudaHost() {
 }
 
 Interpreter::Interpreter(std::unique_ptr CI,
- llvm::Error &Err) {
-  llvm::ErrorAsOutParameter EAO(&Err);
+ llvm::Error &ErrOut) {
+  llvm::ErrorAsOutParameter EAO(&ErrOut);
   auto LLVMCtx = std::make_unique();
   TSCtx = std::make_unique(std::move(LLVMCtx));
-  IncrParser = std::make_unique(*this, std::move(CI),
-   *TSCtx->getContext(), Err);
+  IncrParser = std::make_unique(
+  *this, std::move(CI), *TSCtx->getContext(), ErrOut);
+  if (ErrOut)
+return;
+
+  // Not all frontends support code-generation, e.g. ast-dump actions don't
+  if (IncrParser->getCodeGen()) {
+if (llvm::Error Err = CreateExecutor()) {
+  ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
+  return;
+}
+
+// Process the PTUs that came from initialization. For example -include 
will
+// give us a header that's processed at initialization of the preprocessor.
+for (PartialTranslationUnit &PTU : IncrParser->getPTUs())
+  if (llvm::Error Err = Execute(PTU)) {
+ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
+return;
+  }
+  }
 }
 
 Interpreter::~Interpreter() {
@@ -375,6 +393,10 @@ Interpreter::Parse(llvm::StringRef Code) {
 llvm::Error Interpreter::CreateExecutor() {
   const clang::TargetInfo &TI =
   getCompilerInstance()->getASTContext().getTargetInfo();
+  if (!IncrParser->getCodeGen())
+return llvm::make_error("Operation failed. "
+   "No code generator available",
+   std::error_code());
   llvm::Error Err = llvm::Error::success();
   auto Executor = std::make_unique(*TSCtx, Err, TI);
   if (!Err)
diff --git a/clang/test/Interpreter/execute.cpp 
b/clang/test/Interpreter/execute.cpp
index 6e73ed3927e815..534a54ed94fba2 100644
--- a/clang/test/Interpreter/execute.cpp
+++ b/clang/test/Interpreter/execute.cpp
@@ -7,6 +7,8 @@
 
 // RUN: cat %s | clang-repl | FileCheck %s
 // RUN: cat %s | clang-repl -Xcc -O2 | FileCheck %s
+// RUN: clang-repl -Xcc -include -Xcc %s | FileCheck %s
+// RUN: clang-repl -Xcc -fsyntax-only -Xcc -include -Xcc %s
 extern "C" int printf(const char *, ...);
 int i = 42;
 auto r1 = printf("i = %d\n", i);
@@ -19,5 +21,3 @@ auto r2 = printf("S[f=%f, m=0x%llx]\n", s.f, 
reinterpret_cast


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


[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)

2024-03-11 Thread Stefan Gränitz via cfe-commits

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


[clang] [clang-repl] Expose CreateExecutor() and ResetExecutor() in extended Interpreter interface (PR #84460)

2024-03-11 Thread Stefan Gränitz via cfe-commits

weliveindetail wrote:

> > Do you mind incorporating this patch so that we avoid churn?
> 
> Sure. Essentially, this drops lazy creation of the executor and makes it 
> dependent on the frontend action explicitly. Fine for me. We can still expose 
> explicit setup/tear-down.

@vgvassilev I moved it into the separate review 
https://github.com/llvm/llvm-project/pull/84758, because it has unexpected 
side-effects.

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


[clang] [llvm] [analyzer] Mention possibility of underflow in array overflow errors (PR #84201)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,NagyDonat
 ,Balazs Benics ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/84201

>From 74c7c04cb456c0a058ca36a2ca4ffa4d70d576e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Wed, 6 Mar 2024 18:09:02 +0100
Subject: [PATCH 1/5] [analyzer] Mention possibility of underflow in array
 overflow errors

The checker alpha.security.ArrayBoundV2 performs bounds checking in two
steps: first it checks for underflow, and if it isn't guaranteed then it
assumes that there is no underflow. After this, it checks for overflow,
and if it's guaranteed or the index is tainted then it reports it.

This meant that in situations where overflow and underflow are both
possible (but the index is either tainted or guaranteed to be invalid),
the checker was reporting an overflow error.

This commit modifies the messages printed in these cases to mention the
possibility of an underflow.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 37 +++-
 .../test/Analysis/out-of-bounds-diagnostics.c | 56 ++-
 .../test/Analysis/taint-diagnostic-visitor.c  |  2 +-
 3 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index 29eb932584027d..664d26b00a3cab 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -83,6 +83,8 @@ class StateUpdateReporter {
 AssumedUpperBound = UpperBoundVal;
   }
 
+  bool assumedNonNegative() { return AssumedNonNegative; }
+
   const NoteTag *createNoteTag(CheckerContext &C) const;
 
 private:
@@ -402,7 +404,8 @@ static bool tryDividePair(std::optional &Val1,
 }
 
 static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region,
-   NonLoc Offset, NonLoc Extent, SVal Location) {
+   NonLoc Offset, NonLoc Extent, SVal Location,
+   bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   const auto *EReg = Location.getAsRegion()->getAs();
   assert(EReg && "this checker only handles element access");
@@ -414,6 +417,7 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity();
 
   bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize);
+  const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index";
 
   SmallString<256> Buf;
   llvm::raw_svector_ostream Out(Buf);
@@ -421,10 +425,12 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   if (!ExtentN && !UseByteOffsets)
 Out << "'" << ElemType.getAsString() << "' element in ";
   Out << RegName << " at ";
-  if (OffsetN) {
-Out << (UseByteOffsets ? "byte offset " : "index ") << *OffsetN;
+  if (AssumedNonNegative) {
+Out << "a negative or overflowing " << OffsetOrIndex;
+  } else if (OffsetN) {
+Out << OffsetOrIndex << " " << *OffsetN;
   } else {
-Out << "an overflowing " << (UseByteOffsets ? "byte offset" : "index");
+Out << "an overflowing " << OffsetOrIndex;
   }
   if (ExtentN) {
 Out << ", while it holds only ";
@@ -441,17 +447,19 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const 
SubRegion *Region,
   Out << "s";
   }
 
-  return {
-  formatv("Out of bound access to memory after the end of {0}", RegName),
-  std::string(Buf)};
+  return {formatv("Out of bound access to memory {0} {1}",
+  AssumedNonNegative ? "around" : "after the end of", RegName),
+  std::string(Buf)};
 }
 
-static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName) {
+static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName,
+ bool AssumedNonNegative) {
   std::string RegName = getRegionName(Region);
   return {formatv("Potential out of bound access to {0} with tainted {1}",
   RegName, OffsetName),
-  formatv("Access of {0} with a tainted {1} that may be too large",
-  RegName, OffsetName)};
+  formatv("Access of {0} with a tainted {1} that may be {2}too large",
+  RegName, OffsetName,
+  AssumedNonNegative ? "negative or " : "")};
 }
 
 const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const {
@@ -603,6 +611,8 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, 
CheckerContext &C) const {
 auto [WithinUpperBound, ExceedsUpperBound] =
 compareValueToThreshold(State, ByteOffset, *KnownSize, SVB);
 
+bool AssumedNonNegative = SUR.assumedNonNegative();
+
 if (ExceedsUpperBound) {
   // The offset may be invalid (>= Size)...
   if (!WithinUpperBound) {
@@ -615,8 +625,9 @@ void ArrayBoundCheckerV2::performCheck(const Expr 

[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 


https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/84469

>From c357aa998204e6693430c801f5b7d3a9e5e09e37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Fri, 8 Mar 2024 13:06:01 +0100
Subject: [PATCH 1/4] [analyzer] Accept C library functions from the `std`
 namespace

Previously, the function `isCLibraryFunction()` and logic relying on it
only accepted functions that are declared directly within a TU (i.e. not
in a namespace or a class). However C++ headers like  declare
many C standard library functions within the namespace `std`, so this
commit ensures that functions within the namespace `std` are also
accepted.

After this commit it will be possible to match functions like `malloc` or
`free` with `CallDescription::Mode::CLibrary`.
---
 .../StaticAnalyzer/Core/PathSensitive/CallDescription.h  | 8 ++--
 clang/lib/StaticAnalyzer/Core/CheckerContext.cpp | 9 ++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
index 3432d2648633c2..7da65734a44cf3 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
@@ -41,12 +41,8 @@ class CallDescription {
 ///  - We also accept calls where the number of arguments or parameters is
 ///greater than the specified value.
 /// For the exact heuristics, see CheckerContext::isCLibraryFunction().
-/// Note that functions whose declaration context is not a TU (e.g.
-/// methods, functions in namespaces) are not accepted as C library
-/// functions.
-/// FIXME: If I understand it correctly, this discards calls where C++ code
-/// refers a C library function through the namespace `std::` via headers
-/// like .
+/// (This mode only matches functions that are declared either directly
+/// within a TU or in the `std::` namespace.)
 CLibrary,
 
 /// Matches "simple" functions that are not methods. (Static methods are
diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp 
b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
index d6d4cec9dd3d4d..c1ae9b441d98d1 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -12,6 +12,7 @@
 
//===--===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringExtras.h"
@@ -87,9 +88,11 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl 
*FD,
   if (!II)
 return false;
 
-  // Look through 'extern "C"' and anything similar invented in the future.
-  // If this function is not in TU directly, it is not a C library function.
-  if (!FD->getDeclContext()->getRedeclContext()->isTranslationUnit())
+  // C library functions are either declared directly within a TU (the common
+  // case) or they are accessed through the namespace `std::` (when they are
+  // used in C++ via headers like ).
+  if (!FD->getDeclContext()->getRedeclContext()->isTranslationUnit() &&
+  !AnalysisDeclContext::isInStdNamespace(FD))
 return false;
 
   // If this function is not externally visible, it is not a C library 
function.

>From 6afadd86a6ee790f58c7339dc019d8c8eac8a6b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Fri, 8 Mar 2024 13:22:27 +0100
Subject: [PATCH 2/4] Don't match methods from the namespace `std`

Only accept those functions whose declaration is _directly_ within the
namespace `std` (that is, not within a class or a sub-namespace).
Transparent declaration contexts (e.g. `extern "C"`) are still allowed,
but this prevents matching methods.
---
 clang/lib/StaticAnalyzer/Core/CheckerContext.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp 
b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
index c1ae9b441d98d1..5e706d17eeae14 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -12,7 +12,6 @@
 
//===--===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringExtras.h"
@@ -91,8 +90,8 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl 
*FD,
   // C library functions are either declared directly within a TU (the common
   // case) or they are accessed through the namespace `s

[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits


@@ -2156,9 +2156,10 @@ def TypeNonNull : TypeAttr {
   let Documentation = [TypeNonNullDocs];
 }
 
-def TypeNullable : TypeAttr {
+def TypeNullable : DeclOrTypeAttr {
   let Spellings = [CustomKeyword<"_Nullable">];
   let Documentation = [TypeNullableDocs];
+//  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;

sam-mccall wrote:

With this enabled, the validation will *only* accept `_Nullable` on class 
declarations, not on types. As far as I can tell, SubjectList can only describe 
declarations.

Other DeclOrTypeAttrs use a commented-out `Subjects` like this, I assume as 
documentation, so I did it here for consistency. I can drop it if you want...

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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Don=C3=A1t?= Nagy ,
=?utf-8?q?Don=C3=A1t?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 


NagyDonat wrote:

@steakhal Thanks for contributing the unit tests, I applied your commit.

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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread Balazs Benics via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 


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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread Balazs Benics via cfe-commits
=?utf-8?q?Don=C3=A1t?= Nagy ,
=?utf-8?q?Don=C3=A1t?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 


https://github.com/steakhal approved this pull request.

I'm good now.

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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread Balazs Benics via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 



@@ -0,0 +1,89 @@
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+#include 
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+testing::AssertionResult extractFunctionDecl(StringRef Code,
+ const FunctionDecl *&Result) {
+  auto ASTUnit = tooling::buildASTFromCode(Code);
+  if (!ASTUnit)
+return testing::AssertionFailure() << "AST construction failed";
+
+  ASTContext &Context = ASTUnit->getASTContext();
+  if (Context.getDiagnostics().hasErrorOccurred())
+return testing::AssertionFailure() << "Compilation error";
+
+  auto Matches = ast_matchers::match(functionDecl().bind("fn"), Context);
+  if (Matches.empty())
+return testing::AssertionFailure() << "No function declaration found";
+
+  if (Matches.size() > 1)
+return testing::AssertionFailure()
+   << "Multiple function declarations found";
+
+  Result = Matches[0].getNodeAs("fn");
+  return testing::AssertionSuccess();
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(void fun();)cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsExternCGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(
+  extractFunctionDecl(R"cpp(extern "C" { void fun(); })cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsStaticGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(static void fun();)cpp", Result));
+  EXPECT_FALSE(CheckerContext::isCLibraryFunction(Result));
+  // FIXME: Shouldn't this be TRUE?
+}

steakhal wrote:

What do you all think about this case?
I thought `static` means the same for `C` in this context, and as such it 
should be accepted by `isCLibraryFunction` - at least that's what I'd expect.
This behavior was likely broken before, thus I don't expect direct actions on 
this.

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits


@@ -4096,6 +4096,11 @@ non-underscored keywords. For example:
   @property (assign, nullable) NSView *superview;
   @property (readonly, nonnull) NSArray *subviews;
 @end
+
+As well as built-in pointer types, ithe nullability attributes can be attached
+to nullable types from the C++ standard library such as ``std::unique_ptr`` and

sam-mccall wrote:

Done.

This makes it easier to get out of sync, but I agree comprehensive docs are 
important.

(Inside Google we often just point people at the code and are able to deploy 
fixes quickly, so docs for these details are less critical and skew is more of 
a concern. So I often have blind spots for this stuff...)

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


[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)

2024-03-11 Thread Stefan Gränitz via cfe-commits


@@ -14,7 +14,7 @@ struct A { int a; A(int a) : a(a) {} virtual ~A(); };
 // PartialTranslationUnit.
 inline A::~A() { printf("~A(%d)\n", a); }
 
-// Create one instance with new and delete it.
+// Create one instance with new and delete it. We crash here now:
 A *a1 = new A(1);

weliveindetail wrote:

With `-O2` this test fails unexpectedly now. Minimal repro:
```
clang-repl> struct A { int a; A(int a) : a(a) {} virtual ~A() {} };
clang-repl> A *a1 = new A(1);
clang-repl: llvm/include/llvm/ADT/SmallVector.h:308: const_reference 
llvm::SmallVectorTemplateCommon::operator[](size_type) 
const [T = llvm::PointerAlignElem]: Assertion `idx < size()' failed.
```

The following still works and thus I assume it's related to 
https://github.com/llvm/llvm-project/commit/c861d32d7c2791bdc058d9d9fbaecc1c2f07b8c7:
```
clang-repl> struct A { int a; A(int a) : a(a) {} virtual ~A() {} }; A *a1 = new 
A(1);
```

@hahnjo Maybe we now process init code that clashes with your above fix. Do you 
think that's possible? Any idea how to handle it? If possible, I'd like to 
submit the patch as-is with the test `XFAIL`ed for later investigation.

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


[clang] [Clang][C++23] Implement P2448R2: Relaxing some constexpr restrictions (PR #77753)

2024-03-11 Thread Stephan Bergmann via cfe-commits

stbergmann wrote:

I think the discourse thread [Clang is overly aggressive when evaluating 
constexpr 
functions](https://discourse.llvm.org/t/clang-is-overly-aggressive-when-evaluating-constexpr-functions/67006)
 is relevant here.

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits


@@ -1494,6 +1494,15 @@ void 
Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
   }
 }
 
+void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {
+  while (Tok.is(tok::kw__Nullable)) {

sam-mccall wrote:

It's not important that we accept it, but I think better than changing this to 
`if`:

- consistent with other attributes: we accept `struct [[nodiscard]] 
[[nodiscard]] S{};`
- if we forbid this here by not parsing the second `_Nullable` as an attribute, 
we'll parse it as a class name instead which I think is unlikely to be the 
intent. The follow-on diagnostics are pretty bad.
- on the other hand, if we forbid this elsewhere by checking the attribute 
list, this costs extra ad-hoc code that (I think) we've decided isn't worth it 
for other attributes

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits

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


[clang] [llvm] [Driver] Default -msmall-data-limit= to 0 and clean up code (PR #83093)

2024-03-11 Thread Kito Cheng via cfe-commits

kito-cheng wrote:

There is some discussion in last (2024/2/29) LLVM sync up meeting: We all agree 
that might not useful in linux target and those platforms disable GP 
relaxation, like Android and fuchsia; However it's still useful for embedded 
toolchain, so this change may surprise those embedded toolchain user - cause 
some code size regression due to this change; although lld NOT default enable 
GP relaxation and also not implement all GP relaxation (`R_RISCV_PCREL_HI20` + 
`R_RISCV_PCREL_LO12_I` or `R_RISCV_PCREL_LO12_S` is missing), but user may use 
GNU linker or proprietary linker, so people would like to keep some case using 
same default in some case.

---

Back to the implementation - yes, GCC is not support `-G` in this case, but why 
clang support `-G`? it's kinda inherit from the MIPS and Hexagon, they defined 
`-msmall-data-threshold` and then alias to `-G`, so RISC-V also follow the same 
convention: `-msmall-data-limit=` is alias to `-G` (that's my understanding 
after archaeology, although I work with Shiva at that timing but I don't have 
too much memory about that).

> -mcmodel=large doesn't work for RISC-V yet, so the special case is strange.

My best guess is that is because @ShivaChen was working for Andes at that 
timing, and the patch is extracted from downstream source tree and it already 
has that logic, and no body notice that during review process...:P

[1] https://reviews.llvm.org/D57497

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


[clang] Add bit-precise overloads for builtin operators (PR #84755)

2024-03-11 Thread via cfe-commits


@@ -8955,6 +8962,22 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// _BitInt overloads are a bit special. We don't want to add candidates
+/// for the entire family of _BitInt types, so instead we only add
+/// candidates for the unique, unqualified _BitInt types present in the
+/// candidate type set. The candidate set already handled ensuring the type

cor3ntin wrote:

This comment is a bit weird imo. "We don't want to add candidates for the 
entire family of _BitInt types" seems a bit obvious (and if we wanted to do 
that, wouldn't we need a lot more special handling any way?

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


[clang] Add bit-precise overloads for builtin operators (PR #84755)

2024-03-11 Thread via cfe-commits


@@ -8955,6 +8962,22 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// _BitInt overloads are a bit special. We don't want to add candidates
+/// for the entire family of _BitInt types, so instead we only add
+/// candidates for the unique, unqualified _BitInt types present in the
+/// candidate type set. The candidate set already handled ensuring the type
+/// is unqualified and canonical, but because we're adding from N different
+/// sets, we need to do some extra work to unique things. Copy the
+/// candidates into a unique set, then copy from that set into the list of
+/// arithmetic types.
+llvm::SmallSetVector BitIntCandidates;
+llvm::for_each(CandidateTypes, [&BitIntCandidates](
+   BuiltinCandidateTypeSet &Candidate) {
+  for (QualType BitTy : Candidate.bitint_types())
+BitIntCandidates.insert(CanQualType::CreateUnsafe(BitTy));
+});
+llvm::copy(BitIntCandidates, std::back_inserter(ArithmeticTypes));

cor3ntin wrote:

```suggestion
llvm::move(BitIntCandidates, std::back_inserter(ArithmeticTypes));
```

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


[clang] Add bit-precise overloads for builtin operators (PR #84755)

2024-03-11 Thread Erich Keane via cfe-commits


@@ -8955,6 +8962,22 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// _BitInt overloads are a bit special. We don't want to add candidates
+/// for the entire family of _BitInt types, so instead we only add
+/// candidates for the unique, unqualified _BitInt types present in the
+/// candidate type set. The candidate set already handled ensuring the type
+/// is unqualified and canonical, but because we're adding from N different
+/// sets, we need to do some extra work to unique things. Copy the
+/// candidates into a unique set, then copy from that set into the list of
+/// arithmetic types.
+llvm::SmallSetVector BitIntCandidates;
+llvm::for_each(CandidateTypes, [&BitIntCandidates](
+   BuiltinCandidateTypeSet &Candidate) {
+  for (QualType BitTy : Candidate.bitint_types())
+BitIntCandidates.insert(CanQualType::CreateUnsafe(BitTy));
+});
+llvm::copy(BitIntCandidates, std::back_inserter(ArithmeticTypes));

erichkeane wrote:

I'm concerned about the assert on `9001`.  It seems to me that this changes us 
from being a reasonably 'fixed' list to having a perhaps-unlimited list.  

I think that the intent of that assert is nice (ensuring we can 
small-vector-opt this list), but this section here makes that no longer 
guaranteed, right? 

The `ArithmeticTypesCap` is 24, and we do a `push_back` of 23 other types (by 
my count!).  So adding TWO bit-int types + having all the rest of the types 
enabled causes that assert to fire.

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


[clang] [HIP] Make the new driver bundle outputs for device-only (PR #84534)

2024-03-11 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/84534

>From 1d22692bf3133bbab33485b5e8d65239a7386200 Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Fri, 8 Mar 2024 12:49:38 -0600
Subject: [PATCH] [HIP] Make the new driver bundle outputs for device-only

Summary:
The current behavior of HIP is that when --offload-device-only is set it
still bundles the outputs into a fat binary. Even though this is
different from how all the other targets handle this, it seems to be
dependned on by some tooling so just make it backwards compatible for
the `-fno-gpu-rdc` case.
---
 clang/lib/Driver/Driver.cpp   |  9 -
 clang/test/Driver/hip-binding.hip | 10 +++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index fce43430a91374..21d116656ed13e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4638,7 +4638,10 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
 }
   }
 
-  if (offloadDeviceOnly())
+  // All kinds exit now in device-only mode except for non-RDC mode HIP.
+  if (offloadDeviceOnly() &&
+  (!C.isOffloadingHostKind(Action::OFK_HIP) ||
+   Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false)))
 return C.MakeAction(DDeps, types::TY_Nothing);
 
   if (OffloadActions.empty())
@@ -4671,6 +4674,10 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
  nullptr, C.getActiveOffloadKinds());
   }
 
+  // HIP wants '--offload-device-only' to create a fatbinary by default.
+  if (offloadDeviceOnly())
+return C.MakeAction(DDep, types::TY_Nothing);
+
   // If we are unable to embed a single device output into the host, we need to
   // add each device output as a host dependency to ensure they are still 
built.
   bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](Action *A) {
diff --git a/clang/test/Driver/hip-binding.hip 
b/clang/test/Driver/hip-binding.hip
index 79ec2039edb74c..cb17112c28d90a 100644
--- a/clang/test/Driver/hip-binding.hip
+++ b/clang/test/Driver/hip-binding.hip
@@ -64,10 +64,14 @@
 // MULTI-D-ONLY-NEXT: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]"], 
output: "[[GFX90a:.+]]"
 // MULTI-D-ONLY-NEXT: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: 
["[[GFX90a]]"], output: "[[GFX90a_OUT:.+]]"
 //
-// RUN: not %clang -### --target=x86_64-linux-gnu --offload-new-driver 
-ccc-print-bindings -nogpulib -nogpuinc \
-// RUN:--offload-arch=gfx90a --offload-arch=gfx908 
--offload-device-only -c -o %t %s 2>&1 \
+// RUN: %clang -### --target=x86_64-linux-gnu --offload-new-driver 
-ccc-print-bindings -nogpulib -nogpuinc \
+// RUN:--offload-arch=gfx90a --offload-arch=gfx908 
--offload-device-only -c -o a.out %s 2>&1 \
 // RUN: | FileCheck -check-prefix=MULTI-D-ONLY-O %s
-// MULTI-D-ONLY-O: error: cannot specify -o when generating multiple output 
files
+//  MULTI-D-ONLY-O: "amdgcn-amd-amdhsa" - "clang", inputs: 
["[[INPUT:.+]]"], output: "[[GFX908_OBJ:.+]]"
+// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: 
["[[GFX908_OBJ]]"], output: "[[GFX908:.+]]"
+// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]"], 
output: "[[GFX90A_OBJ:.+]]"
+// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: 
["[[GFX90A_OBJ]]"], output: "[[GFX90A:.+]]"
+// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: 
["[[GFX908]]", "[[GFX90A]]"], output: "a.out"
 
 //
 // Check to ensure that we can use '-fsyntax-only' for HIP output with the new

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

2024-03-11 Thread Erich Keane via cfe-commits

erichkeane wrote:

> > Left my comment on the main list, but I don't see this as a well motivated 
> > change, and even if GCC supported it, it would still be a very difficult to 
> > motivate extension without massive historical workloads already using it.
> 
> This is needed by the Linux kernel, and is in active use. Directly converting 
> from [0] to [] isn't possible due to all the places flex arrays are used in 
> unions. Linux is working around this by tricking the syntax checker 
> currently, which needlessly complicates things. There are currently over 200 
> separate unions using the work-around.
> 
> So, this fixes the accidental lack of the existing [0] extensions not being 
> directly applied to [], and doesn't cause problems for any other users. What 
> solution should Linux use if not fixing this directly nor providing something 
> like -fflex-array-extensions?

I don't see this as being 'accidental', see the GCC bug, Martin makes good 
points: with the `0`, this is a valid extension point, without, it is not.

It seems that Martin @ GCC isn't willing to make this change, or at least isn't 
compelled either, so I'd prefer whatever we do to be in lockstep with them, if 
we choose to do anything.

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits


@@ -215,6 +215,18 @@ void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl 
*Record) {
   inferGslPointerAttribute(Record, Record);
 }
 
+void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) {
+  static llvm::StringSet<> Nullable{
+  "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",

sam-mccall wrote:

I don't think our nullability concept is a good match for weak pointers - they 
don't behave like other pointers.

If a managed object is shared across threads, then the nullable/non-null 
distinction isn't useful. Allowing it to be used in contracts is probably 
harmful (attractive nuisance & breaks analyses that treat nullable objects 
generically). Since pointers may become null at any point without running any 
code, implementations should always treat them as nullable, generic static 
analysis gives incorrect results, and dynamic checks are racy. Threads are 
involved reasonably often and it's not locally possible to tell.

In the absence of threads, `weak_ptr`s that must not be null should almost 
always be `shared_ptr _Nonnull` instead, and probably are. (This isn't a 
strong objection: `T* _Nonnull` is useful despite `T&` existing - but raw 
pointers are *way* more common than weak ones).

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits


@@ -5955,6 +5955,20 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D,
   D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
 }
 
+static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (AL.isUsedAsTypeAttr())
+return;
+
+  if (auto *CRD = dyn_cast(D);
+  !D || !(CRD->isClass() || CRD->isStruct())) {

sam-mccall wrote:

Oops, this was supposed to be `!CRD`! Fixed & will add a testcase.

> Struct as the Subject in Attr.td 

Yeah, unfortunately that doesn't seem to work with attributes that can also 
appear on types :-(

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


[clang] [clang][nullability] allow _Nonnull etc on nullable class types (PR #82705)

2024-03-11 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall updated 
https://github.com/llvm/llvm-project/pull/82705

>From eccc46840e343e7ba15200cd4b81316a51c46943 Mon Sep 17 00:00:00 2001
From: Sam McCall 
Date: Thu, 22 Feb 2024 16:00:44 +0100
Subject: [PATCH 1/2] [clang][nullability] allow _Nonnull etc on nullable class
 types

This enables clang and external nullability checkers to make use of
these annotations on nullable C++ class types like unique_ptr.

These types are recognized by the presence of the _Nullable attribute.
Nullable standard library types implicitly receive this attribute.

Existing static warnings for raw pointers are extended to smart pointers:

- nullptr used as return value or argument for non-null functions
  (`-Wnonnull`)
- assigning or initializing nonnull variables with nullable values
  (`-Wnullable-to-nonnull-conversion`)

It doesn't implicitly add these attributes based on the assume_nonnull
pragma, nor warn on missing attributes where the pragma would apply them.
I'm not confident that the pragma's current behavior will work well for
C++ (where type-based metaprogramming is much more common than C/ObjC).
We'd like to revisit this once we have more implementation experience.

Support can be detected as `__has_feature(nullability_on_classes)`.
This is needed for back-compatibility, as previously clang would issue a
hard error when _Nullable appears on a smart pointer.

UBSan's `-fsanitize=nullability` will not check smart-pointer types.
It can be made to do so by synthesizing calls to `operator bool`, but
that's left for future work.
---
 clang/include/clang/Basic/Attr.td  |  3 +-
 clang/include/clang/Basic/AttrDocs.td  | 16 +++
 clang/include/clang/Basic/Features.def |  1 +
 clang/include/clang/Parse/Parser.h |  1 +
 clang/include/clang/Sema/Sema.h|  3 ++
 clang/lib/AST/Type.cpp | 29 +++-
 clang/lib/CodeGen/CGCall.cpp   |  3 +-
 clang/lib/CodeGen/CodeGenFunction.cpp  |  3 +-
 clang/lib/Parse/ParseDeclCXX.cpp   | 33 ++
 clang/lib/Sema/SemaAttr.cpp| 12 +
 clang/lib/Sema/SemaChecking.cpp|  9 
 clang/lib/Sema/SemaDecl.cpp|  4 +-
 clang/lib/Sema/SemaDeclAttr.cpp| 18 
 clang/lib/Sema/SemaInit.cpp|  5 +++
 clang/lib/Sema/SemaOverload.cpp|  7 +++
 clang/lib/Sema/SemaTemplate.cpp|  1 +
 clang/lib/Sema/SemaType.cpp| 18 ++--
 clang/test/SemaCXX/nullability.cpp | 62 +-
 18 files changed, 199 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index fa191c7378dba4..f75aa126cbb939 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2156,9 +2156,10 @@ def TypeNonNull : TypeAttr {
   let Documentation = [TypeNonNullDocs];
 }
 
-def TypeNullable : TypeAttr {
+def TypeNullable : DeclOrTypeAttr {
   let Spellings = [CustomKeyword<"_Nullable">];
   let Documentation = [TypeNullableDocs];
+//  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
 }
 
 def TypeNullableResult : TypeAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b96fbddd51154c..8c248fb052f19e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4096,6 +4096,11 @@ non-underscored keywords. For example:
   @property (assign, nullable) NSView *superview;
   @property (readonly, nonnull) NSArray *subviews;
 @end
+
+As well as built-in pointer types, ithe nullability attributes can be attached
+to nullable types from the C++ standard library such as ``std::unique_ptr`` and
+``std::function``, as well as C++ classes marked with the ``_Nullable``
+attribute.
   }];
 }
 
@@ -4130,6 +4135,17 @@ The ``_Nullable`` nullability qualifier indicates that a 
value of the
 int fetch_or_zero(int * _Nullable ptr);
 
 a caller of ``fetch_or_zero`` can provide null.
+
+The ``_Nullable`` attribute on classes indicates that the given class can
+represent null values, and so the ``_Nullable``, ``_Nonnull`` etc qualifiers
+make sense for this type. For example:
+
+  .. code-block:: c
+
+class _Nullable ArenaPointer { ... };
+
+ArenaPointer _Nonnull x = ...;
+ArenaPointer _Nullable y = nullptr;
   }];
 }
 
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 5fad5fc3623cb6..7c0755b7318306 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -94,6 +94,7 @@ EXTENSION(define_target_os_macros,
 FEATURE(enumerator_attributes, true)
 FEATURE(nullability, true)
 FEATURE(nullability_on_arrays, true)
+FEATURE(nullability_on_classes, true)
 FEATURE(nullability_nullable_result, true)
 FEATURE(memory_sanitizer,
 LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 071520f535bc95..3d858

[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 



@@ -0,0 +1,89 @@
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+#include 
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+testing::AssertionResult extractFunctionDecl(StringRef Code,
+ const FunctionDecl *&Result) {
+  auto ASTUnit = tooling::buildASTFromCode(Code);
+  if (!ASTUnit)
+return testing::AssertionFailure() << "AST construction failed";
+
+  ASTContext &Context = ASTUnit->getASTContext();
+  if (Context.getDiagnostics().hasErrorOccurred())
+return testing::AssertionFailure() << "Compilation error";
+
+  auto Matches = ast_matchers::match(functionDecl().bind("fn"), Context);
+  if (Matches.empty())
+return testing::AssertionFailure() << "No function declaration found";
+
+  if (Matches.size() > 1)
+return testing::AssertionFailure()
+   << "Multiple function declarations found";
+
+  Result = Matches[0].getNodeAs("fn");
+  return testing::AssertionSuccess();
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(void fun();)cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsExternCGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(
+  extractFunctionDecl(R"cpp(extern "C" { void fun(); })cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsStaticGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(static void fun();)cpp", Result));
+  EXPECT_FALSE(CheckerContext::isCLibraryFunction(Result));
+  // FIXME: Shouldn't this be TRUE?
+}

NagyDonat wrote:

The method `isCLibraryFunction()` applies a heuristic that C library functions 
must be externally visible (unless they're inlined):
```cpp
  // If this function is not externally visible, it is not a C library function.
  // Note that we make an exception for inline functions, which may be
  // declared in header files without external linkage.
  if (!FD->isInlined() && !FD->isExternallyVisible())
return false;
```
I think this is a reasonable heuristic that should not cause false negatives (I 
don't think that we can have a library function that isn't inlined and isn't 
externally visible) and might prevent a few false positives.

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


[clang] [Clang][Sema] Fix crash when using name of UnresolvedUsingValueDecl with template arguments (PR #83842)

2024-03-11 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

So, it seems that this crash occurs because we filter out all non-template 
functions, which will trigger ADL if the only class member we found was a 
non-template function.

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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 



@@ -0,0 +1,89 @@
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+#include 
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+testing::AssertionResult extractFunctionDecl(StringRef Code,
+ const FunctionDecl *&Result) {
+  auto ASTUnit = tooling::buildASTFromCode(Code);
+  if (!ASTUnit)
+return testing::AssertionFailure() << "AST construction failed";
+
+  ASTContext &Context = ASTUnit->getASTContext();
+  if (Context.getDiagnostics().hasErrorOccurred())
+return testing::AssertionFailure() << "Compilation error";
+
+  auto Matches = ast_matchers::match(functionDecl().bind("fn"), Context);
+  if (Matches.empty())
+return testing::AssertionFailure() << "No function declaration found";
+
+  if (Matches.size() > 1)
+return testing::AssertionFailure()
+   << "Multiple function declarations found";
+
+  Result = Matches[0].getNodeAs("fn");
+  return testing::AssertionSuccess();
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(void fun();)cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsExternCGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(
+  extractFunctionDecl(R"cpp(extern "C" { void fun(); })cpp", Result));
+  EXPECT_TRUE(CheckerContext::isCLibraryFunction(Result));
+}
+
+TEST(IsCLibraryFunctionTest, AcceptsStaticGlobal) {
+  const FunctionDecl *Result;
+  ASSERT_TRUE(extractFunctionDecl(R"cpp(static void fun();)cpp", Result));
+  EXPECT_FALSE(CheckerContext::isCLibraryFunction(Result));
+  // FIXME: Shouldn't this be TRUE?
+}

NagyDonat wrote:

```suggestion
TEST(IsCLibraryFunctionTest, RejectsNoInlineNoExternalLinkage) {
  // Functions that are neither inlined nor externally visible cannot be C 
library functions.
  const FunctionDecl *Result;
  ASSERT_TRUE(extractFunctionDecl(R"cpp(static void fun();)cpp", Result));
  EXPECT_FALSE(CheckerContext::isCLibraryFunction(Result));
}
```

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


[clang] [llvm] [analyzer] Accept C library functions from the `std` namespace (PR #84469)

2024-03-11 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 
Message-ID:
In-Reply-To: 


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


[clang] [C++20] [Modules] Introduce a tool 'clang-named-modules-querier' and two plugins 'ClangGetUsedFilesFromModulesPlugin' and 'ClangGetDeclsInModulesPlugin' (PR #72956)

2024-03-11 Thread Ben Boeckel via cfe-commits

mathstuf wrote:

> ClangGetUsedFilesFromModulesPlugin

This has a hole where if a currently-unused file is not listed, but it is 
changed in such a way that it now matters (e.g., it changes include order, 
adds/removes includes, etc.), we need to recompile consumers.

> what happens if someone adds an overload, or other interesting name 
> resolution to the module?

We would need to do (at least) one of:

- track considered-but-discarded decls (e.g., if something SFINAE'd away now 
matters because of a new decl);
- track "new" decls since the last compile (not sure how the state tracking 
works here though) and recompile if any show up

>  "col": 12,
>  "kind": "Function",
>  "line": 3,

So we change the decl hash if a comment adds a line? That seems like 
low-hanging fruit to me. Can we enumerate decls and use an index instead? That 
depends on preprocessor state though, so may be hard to externally verify…

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


  1   2   3   4   5   >