[clang] [clang-tools-extra] [libcxx] [clang] Enable sized deallocation by default in C++14 onwards (PR #83774)

2024-03-12 Thread Wang Pengcheng via cfe-commits


@@ -2912,16 +2912,70 @@ static bool sdkSupportsBuiltinModules(const 
Darwin::DarwinPlatformKind &TargetPl
   }
 }
 
-void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-   llvm::opt::ArgStringList &CC1Args,
-   Action::OffloadKind DeviceOffloadKind) 
const {
+static inline llvm::VersionTuple
+sizedDeallocMinVersion(llvm::Triple::OSType OS) {
+  switch (OS) {
+  default:
+break;
+  case llvm::Triple::Darwin:
+  case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.

wangpc-pp wrote:

Aha, because these are what you told me. :-)

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


[clang] [clang-tools-extra] [libcxx] [clang] Enable sized deallocation by default in C++14 onwards (PR #83774)

2024-03-12 Thread Wang Pengcheng via cfe-commits

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


[clang] [clang-tools-extra] [libcxx] [clang] Enable sized deallocation by default in C++14 onwards (PR #83774)

2024-03-12 Thread Wang Pengcheng via cfe-commits

wangpc-pp wrote:

> The `__cpp_sized_deallocation` feature test macro should be set to 201309L

This has been done.
https://github.com/llvm/llvm-project/blob/1d900e298449d43547312364751f730b7a0d07d1/clang/lib/Frontend/InitPreprocessor.cpp#L690C1-L692C1

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


[clang] [clang-tools-extra] [libcxx] [clang] Enable sized deallocation by default in C++14 onwards (PR #83774)

2024-03-12 Thread Wang Pengcheng via cfe-commits

https://github.com/wangpc-pp updated 
https://github.com/llvm/llvm-project/pull/83774

>From 26245679b0f40b510e628aaed091739e9931c29c Mon Sep 17 00:00:00 2001
From: wangpc 
Date: Fri, 14 Jul 2023 10:38:14 +0800
Subject: [PATCH 1/4] [clang] Enable sized deallocation by default in C++14
 onwards

Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

Differential Revision: https://reviews.llvm.org/D112921
---
 .../clangd/unittests/FindTargetTests.cpp  |   4 +-
 .../checkers/misc/new-delete-overloads.cpp|  10 -
 clang/docs/ReleaseNotes.rst   |   4 +
 clang/include/clang/Basic/SizedDeallocation.h |  44 
 clang/include/clang/Driver/Options.td |   5 +-
 clang/lib/Driver/ToolChains/Clang.cpp |  13 +-
 clang/lib/Driver/ToolChains/Darwin.cpp|  41 ++-
 clang/lib/Driver/ToolChains/Darwin.h  |   4 +
 clang/lib/Driver/ToolChains/ZOS.cpp   |   6 +
 clang/test/AST/ast-dump-expr-json.cpp |   2 +-
 clang/test/AST/ast-dump-expr.cpp  |   2 +-
 clang/test/AST/ast-dump-stmt-json.cpp | 244 +-
 clang/test/Analysis/cxxnewexpr-callback.cpp   |   4 +-
 .../basic.stc.dynamic.deallocation/p2.cpp |   2 +-
 clang/test/CXX/drs/dr292.cpp  |   6 +-
 .../test/CXX/expr/expr.unary/expr.new/p14.cpp |   2 +-
 .../CodeGenCXX/cxx1y-sized-deallocation.cpp   |  10 +-
 .../CodeGenCXX/cxx1z-aligned-allocation.cpp   |   6 +-
 .../CodeGenCXX/cxx2a-destroying-delete.cpp|   4 +-
 clang/test/CodeGenCXX/delete-two-arg.cpp  |   4 +-
 clang/test/CodeGenCXX/delete.cpp  |  12 +-
 clang/test/CodeGenCXX/dllimport.cpp   |   4 +-
 clang/test/CodeGenCXX/new.cpp |   6 +-
 .../coro-aligned-alloc-2.cpp  |   2 -
 .../CodeGenCoroutines/coro-aligned-alloc.cpp  |   6 +-
 clang/test/CodeGenCoroutines/coro-alloc.cpp   |   6 +-
 clang/test/CodeGenCoroutines/coro-cleanup.cpp |   6 +-
 clang/test/CodeGenCoroutines/coro-dealloc.cpp |   2 -
 clang/test/CodeGenCoroutines/coro-gro.cpp |   3 +-
 clang/test/CodeGenCoroutines/pr56919.cpp  |   9 +-
 clang/test/Lexer/cxx-features.cpp |  20 +-
 clang/test/PCH/cxx1z-aligned-alloc.cpp|  10 +-
 clang/test/SemaCXX/MicrosoftExtensions.cpp|   8 +-
 .../SemaCXX/builtin-operator-new-delete.cpp   |   2 +-
 .../test/SemaCXX/cxx1y-sized-deallocation.cpp |   2 +-
 .../unavailable_aligned_allocation.cpp|  15 +-
 .../StaticAnalyzer/CallEventTest.cpp  |   2 +-
 clang/www/cxx_status.html |  11 +-
 .../support.dynamic/libcpp_deallocate.sh.cpp  |   3 +
 .../sized_delete_array14.pass.cpp |   8 +-
 .../new.delete.single/sized_delete14.pass.cpp |   8 +-
 41 files changed, 458 insertions(+), 104 deletions(-)
 create mode 100644 clang/include/clang/Basic/SizedDeallocation.h

diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp 
b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 0af6036734ba53..1b7b96281dfaa5 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -839,7 +839,9 @@ TEST_F(TargetDeclTest, OverloadExpr) {
   [[delete]] x;
 }
   )cpp";
-  EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept");
+  // Sized deallocation is enabled by default in C++14 onwards.
+  EXPECT_DECLS("CXXDeleteExpr",
+   "void operator delete(void *, unsigned long) noexcept");
 }
 
 TEST_F(TargetDeclTest, DependentExprs) {
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
index 78f021144b2e19..f86fe8a4c5b14f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
@@ -12,16 +12,6 @@ struct S {
 // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has 
no matching declaration of 'operator delete' at the same scope
 void *operator new(size_t size) noexcept(false);
 
-struct T {
-  // Sized deallocations are not enabled by default, and so this new/delete 
pair
-  // does not match. However, we expect only one warning, for the new, because
-  // the operator delete is a placement delete and we do not warn on 
mismatching
-  // placement operations.
-  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' 
has no matching declaration of 'operator delete' at the same scope
-  void *operator new(size_t size) noexcept;
-  void operator delete(void *ptr, size_t) noexcept; // ok only if sized 
deallocation is enabled
-};
-
 struct U {
   void *operator new(size_t size) noexcept;
   void operator delete(void *ptr) noexcept;
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6f6ce7c6

[clang] [Clang][Sema] Fix a bug on type constraint checking (PR #84671)

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

https://github.com/jcsxky edited https://github.com/llvm/llvm-project/pull/84671
___
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-12 Thread via cfe-commits

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

LGTM, thanks!

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] [Clang][Sema] Fix a bug on type constraint checking (PR #84671)

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

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/84671

>From 52093e782c55fb5492070e8dc8686c06922b0997 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 10 Mar 2024 16:11:18 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on type constraint checking

---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  1 +
 clang/test/Sema/PR84368.cpp| 16 
 3 files changed, 18 insertions(+)
 create mode 100644 clang/test/Sema/PR84368.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88e552d5c46113..0006c2814869d8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -351,6 +351,7 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Fix an issue where missing set friend declaration in template class 
instantiation. (#GH84368).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 20c2c93ac9c7b4..765c5bc689ae1e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1698,6 +1698,7 @@ Decl 
*TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 assert(!Owner->isDependentContext());
 Inst->setLexicalDeclContext(Owner);
 RecordInst->setLexicalDeclContext(Owner);
+Inst->setObjectOfFriendDecl();
 
 if (PrevClassTemplate) {
   Inst->setCommonPtr(PrevClassTemplate->getCommonPtr());
diff --git a/clang/test/Sema/PR84368.cpp b/clang/test/Sema/PR84368.cpp
new file mode 100644
index 00..073530ffd8abea
--- /dev/null
+++ b/clang/test/Sema/PR84368.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++23 -verify %s
+// expected-no-diagnostics
+
+template concept IsOk = requires() { typename T::Float; };
+
+template struct Thing;
+
+template struct Foobar {
+   template struct Inner {
+   template friend struct Thing;
+   };
+};
+
+struct MyType { using Float=float; };
+Foobar::Inner<0> foobar;

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


[clang] [Clang][Sema] Fix a bug on type constraint checking (PR #84671)

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

jcsxky wrote:

> The commit message and release note needs to be MUCH more detailed. Else I 
> think this looks like an acceptable patch.

Thanks for you remind! I have updated commit message and release note to make 
it more clear.

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


[clang] [Clang][Sema] Fix a bug on type constraint checking (PR #84671)

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

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/84671

>From 1b71ce0ece77060591edaf69794e184d58ad9b15 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 10 Mar 2024 16:11:18 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on type constraint checking

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  1 +
 clang/test/Sema/PR84368.cpp| 16 
 3 files changed, 19 insertions(+)
 create mode 100644 clang/test/Sema/PR84368.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88e552d5c46113..12b867330efff1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -351,6 +351,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Fix an issue where missing set friend declaration in template class 
instantiation.
+  Fixes (#GH84368).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 20c2c93ac9c7b4..765c5bc689ae1e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1698,6 +1698,7 @@ Decl 
*TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 assert(!Owner->isDependentContext());
 Inst->setLexicalDeclContext(Owner);
 RecordInst->setLexicalDeclContext(Owner);
+Inst->setObjectOfFriendDecl();
 
 if (PrevClassTemplate) {
   Inst->setCommonPtr(PrevClassTemplate->getCommonPtr());
diff --git a/clang/test/Sema/PR84368.cpp b/clang/test/Sema/PR84368.cpp
new file mode 100644
index 00..073530ffd8abea
--- /dev/null
+++ b/clang/test/Sema/PR84368.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++23 -verify %s
+// expected-no-diagnostics
+
+template concept IsOk = requires() { typename T::Float; };
+
+template struct Thing;
+
+template struct Foobar {
+   template struct Inner {
+   template friend struct Thing;
+   };
+};
+
+struct MyType { using Float=float; };
+Foobar::Inner<0> foobar;

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


[clang] Reland Print library module manifest path again (PR #84881)

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

https://github.com/ChuanqiXu9 created 
https://github.com/llvm/llvm-project/pull/84881

Following of https://github.com/llvm/llvm-project/pull/82160

The reason why the above PR fails is that the `--sysroot` has lower priority 
than the libc++ built from the same source. On the one hand, it matches the 
codes behavior. We will add the built libc++ project paths in the ToolChain 
class. But we will only add the path related to sysroot in Linux class, which 
is derived from the ToolChain classes. So the paths of just built libc++ is in 
the front of the paths relative to sysroot. On the other hand, the behavior 
should be good from the higher level.  Since the just built libc++ has the same 
version number with the just built clang, so it makes sense that these 2 
compilers just matches.

So for patch it self, I hacked it by using resource dir in the test since the 
resource dir has the higher priority, which is not strongly correct since we 
won't do that in practice.

@kaz7 would you like to test on your environment to avoid this get reverted 
again?

On the libc++ side, it shows that it lacks a `modules.json` file for the just 
built libc++ directory. If we don't have that, it will be problematic to use 
std modules from the just built clang and libc++ pair. Then it is not good. And 
I feel it may be problematic for future compiler/standard library developers. 
So I feel this is somewhat  a libc++ issue that need to be fixed.

Also if we don't like the hacked test in the current patch, we must wait for 
libc++ to fix this to proceed. But I feel this is somewhat odd since the test 
of clang shouldn't dependent on libc++.

CC: @mordante 

>From 27665923ce0b9974601d7e5880506e3560bade19 Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 3 Mar 2024 17:58:08 +0100
Subject: [PATCH 1/2] Reland "[clang][modules] Print library module manifest
 path." (#82160)

This implements a way for the compiler to find the modules.json
associated with the C++23 Standard library modules.

This is based on a discussion in SG15. At the moment no Standard library
installs this manifest. #75741 adds this feature in libc++.

This reverts commit 82f424f766be00b037a706a835d0a0663a2680f1.

Disables the tests on non-X86 platforms as suggested.
---
 clang/include/clang/Driver/Driver.h   | 10 +
 clang/include/clang/Driver/Options.td |  3 ++
 clang/lib/Driver/Driver.cpp   | 44 +++
 ...les-print-library-module-manifest-path.cpp | 40 +
 4 files changed, 97 insertions(+)
 create mode 100644 
clang/test/Driver/modules-print-library-module-manifest-path.cpp

diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index c4cab360bab3bb..bcf8c1295f2ddf 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -615,6 +615,16 @@ class Driver {
   // FIXME: This should be in CompilationInfo.
   std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
 
+  /// Lookup the path to the Standard library module manifest.
+  ///
+  /// \param C - The compilation.
+  /// \param TC - The tool chain for additional information on
+  /// directories to search.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetStdModuleManifestPath(const Compilation &C,
+   const ToolChain &TC) const;
+
   /// HandleAutocompletions - Handle --autocomplete by searching and printing
   /// possible flags, descriptions, and its arguments.
   void HandleAutocompletions(StringRef PassedFlags) const;
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index aca8c9b0d5487a..6e7f142789c994 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5374,6 +5374,9 @@ def print_resource_dir : Flag<["-", "--"], 
"print-resource-dir">,
 def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
   HelpText<"Print the paths used for finding libraries and programs">,
   Visibility<[ClangOption, CLOption]>;
+def print_std_module_manifest_path : Flag<["-", "--"], 
"print-library-module-manifest-path">,
+  HelpText<"Print the path for the C++ Standard library module manifest">,
+  Visibility<[ClangOption, CLOption]>;
 def print_targets : Flag<["-", "--"], "print-targets">,
   HelpText<"Print the registered targets">,
   Visibility<[ClangOption, CLOption]>;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 190782a79a2456..eae27769b73ec0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2196,6 +2196,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
 return false;
   }
 
+  if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
+llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
+ << '\n';
+return false;
+  }
+
   if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
 if

[clang] Reland "[clang][modules] Print library module manifest path." (PR #82160)

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

ChuanqiXu9 wrote:

I sent the new PR in https://github.com/llvm/llvm-project/pull/84881. See the 
comments there for details.

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


[clang] Reland Print library module manifest path again (PR #84881)

2024-03-12 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-modules

Author: Chuanqi Xu (ChuanqiXu9)


Changes

Following of https://github.com/llvm/llvm-project/pull/82160

The reason why the above PR fails is that the `--sysroot` has lower priority 
than the libc++ built from the same source. On the one hand, it matches the 
codes behavior. We will add the built libc++ project paths in the ToolChain 
class. But we will only add the path related to sysroot in Linux class, which 
is derived from the ToolChain classes. So the paths of just built libc++ is in 
the front of the paths relative to sysroot. On the other hand, the behavior 
should be good from the higher level.  Since the just built libc++ has the same 
version number with the just built clang, so it makes sense that these 2 
compilers just matches.

So for patch it self, I hacked it by using resource dir in the test since the 
resource dir has the higher priority, which is not strongly correct since we 
won't do that in practice.

@kaz7 would you like to test on your environment to avoid this get 
reverted again?

On the libc++ side, it shows that it lacks a `modules.json` file for the just 
built libc++ directory. If we don't have that, it will be problematic to use 
std modules from the just built clang and libc++ pair. Then it is not good. And 
I feel it may be problematic for future compiler/standard library developers. 
So I feel this is somewhat  a libc++ issue that need to be fixed.

Also if we don't like the hacked test in the current patch, we must wait for 
libc++ to fix this to proceed. But I feel this is somewhat odd since the test 
of clang shouldn't dependent on libc++.

CC: @mordante 

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


4 Files Affected:

- (modified) clang/include/clang/Driver/Driver.h (+10) 
- (modified) clang/include/clang/Driver/Options.td (+3) 
- (modified) clang/lib/Driver/Driver.cpp (+44) 
- (added) clang/test/Driver/modules-print-library-module-manifest-path.cpp 
(+36) 


``diff
diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index c4cab360bab3bb..bcf8c1295f2ddf 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -615,6 +615,16 @@ class Driver {
   // FIXME: This should be in CompilationInfo.
   std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
 
+  /// Lookup the path to the Standard library module manifest.
+  ///
+  /// \param C - The compilation.
+  /// \param TC - The tool chain for additional information on
+  /// directories to search.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetStdModuleManifestPath(const Compilation &C,
+   const ToolChain &TC) const;
+
   /// HandleAutocompletions - Handle --autocomplete by searching and printing
   /// possible flags, descriptions, and its arguments.
   void HandleAutocompletions(StringRef PassedFlags) const;
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index aca8c9b0d5487a..6e7f142789c994 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5374,6 +5374,9 @@ def print_resource_dir : Flag<["-", "--"], 
"print-resource-dir">,
 def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
   HelpText<"Print the paths used for finding libraries and programs">,
   Visibility<[ClangOption, CLOption]>;
+def print_std_module_manifest_path : Flag<["-", "--"], 
"print-library-module-manifest-path">,
+  HelpText<"Print the path for the C++ Standard library module manifest">,
+  Visibility<[ClangOption, CLOption]>;
 def print_targets : Flag<["-", "--"], "print-targets">,
   HelpText<"Print the registered targets">,
   Visibility<[ClangOption, CLOption]>;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 190782a79a2456..eae27769b73ec0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2196,6 +2196,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
 return false;
   }
 
+  if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
+llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
+ << '\n';
+return false;
+  }
+
   if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
 if (std::optional RuntimePath = TC.getRuntimePath())
   llvm::outs() << *RuntimePath << '\n';
@@ -6185,6 +6191,44 @@ std::string Driver::GetProgramPath(StringRef Name, const 
ToolChain &TC) const {
   return std::string(Name);
 }
 
+std::string Driver::GetStdModuleManifestPath(const Compilation &C,
+ const ToolChain &TC) const {
+  std::string error = "";
+
+  switch (TC.GetCXXStdlibType(C.getArgs())) {
+  case ToolChain::CST_Libcxx: {
+std::string lib = GetFilePath("libc++.so", TC);
+
+// Note when there are multiple flavours of libc++ the module json 

[clang] 1dd104d - [clang][Interp] Implement _Complex Not unary operators

2024-03-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-12T07:48:56+01:00
New Revision: 1dd104db59d145d516a5e9cbb081ed01262961ef

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

LOG: [clang][Interp] Implement _Complex Not unary operators

This only happens in C as far as I can tell. The complex varialbe
will have undergone a conversion to bool in C++ before reaching
the unary operator.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.c

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 0dd645990d1d58..da4a8f88f1396a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3182,6 +3182,17 @@ bool ByteCodeExprGen::VisitComplexUnaryOperator(
   case UO_AddrOf:
 return this->delegate(SubExpr);
 
+  case UO_LNot:
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitComplexBoolCast(SubExpr))
+  return false;
+if (!this->emitInvBool(E))
+  return false;
+if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
+  return this->emitCast(PT_Bool, ET, E);
+return true;
+
   case UO_Real:
 return this->emitComplexReal(SubExpr);
 

diff  --git a/clang/test/AST/Interp/complex.c b/clang/test/AST/Interp/complex.c
index c9c2efb5974531..b5f30b87baa79a 100644
--- a/clang/test/AST/Interp/complex.c
+++ b/clang/test/AST/Interp/complex.c
@@ -14,3 +14,8 @@ void blah() {
 _Static_assert((0.0 + 0.0j) == (0.0 + 0.0j), "");
 _Static_assert((0.0 + 0.0j) != (0.0 + 0.0j), ""); // both-error {{static 
assertion}} \
   // both-note {{evaluates to}}
+
+const _Complex float FC = {0.0f, 0.0f};
+_Static_assert(!FC, "");
+const _Complex float FI = {0, 0};
+_Static_assert(!FI, "");



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


[clang] [clang][Interp] Merge ByteCodeExprGen and ByteCodeStmtGen (PR #83683)

2024-03-12 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

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


[clang] 103469b - [clang][Interp] Implement more easy _Complex unary operators

2024-03-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-12T08:51:12+01:00
New Revision: 103469b5f7467d5df15799c2d8ad150729bc33bd

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

LOG: [clang][Interp] Implement more easy _Complex unary operators

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index da4a8f88f1396a..86304a54473cea 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3138,16 +3138,17 @@ bool 
ByteCodeExprGen::VisitComplexUnaryOperator(
 return this->discard(SubExpr);
 
   std::optional ResT = classify(E);
+  auto prepareResult = [=]() -> bool {
+if (!ResT && !Initializing) {
+  std::optional LocalIndex =
+  allocateLocal(SubExpr, /*IsExtended=*/false);
+  if (!LocalIndex)
+return false;
+  return this->emitGetPtrLocal(*LocalIndex, E);
+}
 
-  // Prepare storage for result.
-  if (!ResT && !Initializing) {
-std::optional LocalIndex =
-allocateLocal(SubExpr, /*IsExtended=*/false);
-if (!LocalIndex)
-  return false;
-if (!this->emitGetPtrLocal(*LocalIndex, E))
-  return false;
-  }
+return true;
+  };
 
   // The offset of the temporary, if we created one.
   unsigned SubExprOffset = ~0u;
@@ -3167,6 +3168,8 @@ bool ByteCodeExprGen::VisitComplexUnaryOperator(
 
   switch (E->getOpcode()) {
   case UO_Minus:
+if (!prepareResult())
+  return false;
 if (!createTemp())
   return false;
 for (unsigned I = 0; I != 2; ++I) {
@@ -3179,7 +3182,9 @@ bool ByteCodeExprGen::VisitComplexUnaryOperator(
 }
 break;
 
-  case UO_AddrOf:
+  case UO_Plus:   // +x
+  case UO_AddrOf: // &x
+  case UO_Deref:  // *x
 return this->delegate(SubExpr);
 
   case UO_LNot:



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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Haohai Wen via cfe-commits


@@ -2434,6 +2449,15 @@ usual build cycle when using sample profilers for 
optimization:
it provides better call information, which improves the accuracy of
the profile data.
 
+   When using SEP:
+
+   .. code-block:: console
+
+ $ sep -start -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr 
no_filter:usr -perf-script ip,brstack -app ./code

HaohaiWen wrote:

Should we add `-out code.tb7 to sep'? Otherwise sep will generate a temp name 
(tbs17644.perf.data.script in my env).
e.g.
```
sep -start -out code.tb7 -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr 
no_filter:usr -perf-script brstack -app ./code
```

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Haohai Wen via cfe-commits


@@ -2434,6 +2449,15 @@ usual build cycle when using sample profilers for 
optimization:
it provides better call information, which improves the accuracy of
the profile data.
 
+   When using SEP:
+
+   .. code-block:: console
+
+ $ sep -start -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr 
no_filter:usr -perf-script ip,brstack -app ./code
+
+   This produces a ``perf.data.script`` output which can be used with

HaohaiWen wrote:

Should change to code.perf.data.script if specify -out code.tb7

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Haohai Wen via cfe-commits


@@ -2434,6 +2449,15 @@ usual build cycle when using sample profilers for 
optimization:
it provides better call information, which improves the accuracy of
the profile data.
 
+   When using SEP:
+
+   .. code-block:: console
+
+ $ sep -start -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr 
no_filter:usr -perf-script ip,brstack -app ./code

HaohaiWen wrote:

I think we should remove ip on output perf script and just leave `-perf-script 
brstack`

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


[clang] [clang][ASTMatchers] Fix forEachArgumentWithParam* for deducing "this" operator calls (PR #84887)

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

https://github.com/steakhal created 
https://github.com/llvm/llvm-project/pull/84887

This is a follow-up commit of #84446.
In this patch, I demonstrate that `forEachArgumentWithParam` and 
`forEachArgumentWithParamType` did not correctly handle the presence of the 
explicit object parameter for operator calls.

Prior to this patch, the matcher would skip the first (and only) argument of 
the operator call if the explicit object param was used.

Note that I had to move the definition of `isExplicitObjectMemberFunction`, to 
be declared before the matcher I fix to be visible.

I also had to do some gymnastics for passing the language standard version 
command-line flags to the invocation as `matchAndVerifyResultTrue` wasn't 
really considered for non-c++11 code. See the that it always prepends 
`-std=gnu++11` to the command-line arguments. I workarounded it by accepting 
extra args, which get appended, thus possibly overriding the hardcoded 
arguments.

I'm not sure if this qualifies for backporting to clang-18, but I figure it 
might be useful for some vendors (like us).
But we are also happy to cherry-pick this fix to downstream. Let me know if you 
want this to be backported or not.

>From 61f63a34f68661c12b63ba8d1a1a3e8b550ed076 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Tue, 12 Mar 2024 09:08:19 +0100
Subject: [PATCH] [clang][ASTMatchers] Fix forEachArgumentWithParam* for
 deducing "this" operator calls

This is a follow-up commit of #84446.
In this patch, I demonstrate that `forEachArgumentWithParam` and
`forEachArgumentWithParamType` did not correctly handle the presence of
the explicit object parameter for operator calls.

Prior to this patch, the matcher would skip the first (and only) argument
of the operator call if the explicit object param was used.

Note that I had to move the definition of `isExplicitObjectMemberFunction`,
to be declared before the matcher I fix to be visible.
---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/ASTMatchers/ASTMatchers.h | 59 -
 clang/unittests/ASTMatchers/ASTMatchersTest.h | 36 +++
 .../ASTMatchers/ASTMatchersTraversalTest.cpp  | 63 +++
 4 files changed, 119 insertions(+), 41 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88e552d5c46113..dcc0c2f2cc40c6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -447,6 +447,8 @@ AST Matchers
 
 - ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
 - Add ``isExplicitObjectMemberFunction``.
+- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to
+  not skip the explicit object parameter for operator calls.
 
 clang-format
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 96dbcdc344e131..2f71053d030f68 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -5032,6 +5032,25 @@ AST_POLYMORPHIC_MATCHER_P2(hasParameter,
   && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
 }
 
+/// Matches if the given method declaration declares a member function with an
+/// explicit object parameter.
+///
+/// Given
+/// \code
+/// struct A {
+///  int operator-(this A, int);
+///  void fun(this A &&self);
+///  static int operator()(int);
+///  int operator+(int);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
+/// methods but not the last two.
+AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
+  return Node.isExplicitObjectMemberFunction();
+}
+
 /// Matches all arguments and their respective ParmVarDecl.
 ///
 /// Given
@@ -5060,10 +5079,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
   // argument of the method which should not be matched against a parameter, so
   // we skip over it here.
   BoundNodesTreeBuilder Matches;
-  unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
-  .matches(Node, Finder, &Matches)
-  ? 1
-  : 0;
+  unsigned ArgIndex =
+  cxxOperatorCallExpr(
+  callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction()
+  .matches(Node, Finder, &Matches)
+  ? 1
+  : 0;
   int ParamIndex = 0;
   bool Matched = false;
   for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
@@ -5121,11 +5142,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
   // argument of the method which should not be matched against a parameter, so
   // we skip over it here.
   BoundNodesTreeBuilder Matches;
-  unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
-  .matches(Node, Finder, &Matches)
-  ? 1
-  : 0;
-
+  unsigned ArgIndex =
+  cxxOperatorCallExpr(
+  callee(cxxMethodDecl(unl

[clang] [clang][ASTMatchers] Fix forEachArgumentWithParam* for deducing "this" operator calls (PR #84887)

2024-03-12 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Balazs Benics (steakhal)


Changes

This is a follow-up commit of #84446.
In this patch, I demonstrate that `forEachArgumentWithParam` and 
`forEachArgumentWithParamType` did not correctly handle the presence of the 
explicit object parameter for operator calls.

Prior to this patch, the matcher would skip the first (and only) argument of 
the operator call if the explicit object param was used.

Note that I had to move the definition of `isExplicitObjectMemberFunction`, to 
be declared before the matcher I fix to be visible.

I also had to do some gymnastics for passing the language standard version 
command-line flags to the invocation as `matchAndVerifyResultTrue` wasn't 
really considered for non-c++11 code. See the that it always prepends 
`-std=gnu++11` to the command-line arguments. I workarounded it by accepting 
extra args, which get appended, thus possibly overriding the hardcoded 
arguments.

I'm not sure if this qualifies for backporting to clang-18, but I figure it 
might be useful for some vendors (like us).
But we are also happy to cherry-pick this fix to downstream. Let me know if you 
want this to be backported or not.

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


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+31-28) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersTest.h (+23-13) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (+63) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88e552d5c46113..dcc0c2f2cc40c6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -447,6 +447,8 @@ AST Matchers
 
 - ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
 - Add ``isExplicitObjectMemberFunction``.
+- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to
+  not skip the explicit object parameter for operator calls.
 
 clang-format
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 96dbcdc344e131..2f71053d030f68 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -5032,6 +5032,25 @@ AST_POLYMORPHIC_MATCHER_P2(hasParameter,
   && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
 }
 
+/// Matches if the given method declaration declares a member function with an
+/// explicit object parameter.
+///
+/// Given
+/// \code
+/// struct A {
+///  int operator-(this A, int);
+///  void fun(this A &&self);
+///  static int operator()(int);
+///  int operator+(int);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
+/// methods but not the last two.
+AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
+  return Node.isExplicitObjectMemberFunction();
+}
+
 /// Matches all arguments and their respective ParmVarDecl.
 ///
 /// Given
@@ -5060,10 +5079,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
   // argument of the method which should not be matched against a parameter, so
   // we skip over it here.
   BoundNodesTreeBuilder Matches;
-  unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
-  .matches(Node, Finder, &Matches)
-  ? 1
-  : 0;
+  unsigned ArgIndex =
+  cxxOperatorCallExpr(
+  callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction()
+  .matches(Node, Finder, &Matches)
+  ? 1
+  : 0;
   int ParamIndex = 0;
   bool Matched = false;
   for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
@@ -5121,11 +5142,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
   // argument of the method which should not be matched against a parameter, so
   // we skip over it here.
   BoundNodesTreeBuilder Matches;
-  unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
-  .matches(Node, Finder, &Matches)
-  ? 1
-  : 0;
-
+  unsigned ArgIndex =
+  cxxOperatorCallExpr(
+  callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction()
+  .matches(Node, Finder, &Matches)
+  ? 1
+  : 0;
   const FunctionProtoType *FProto = nullptr;
 
   if (const auto *Call = dyn_cast(&Node)) {
@@ -6366,25 +6388,6 @@ AST_MATCHER(CXXMethodDecl, isConst) {
   return Node.isConst();
 }
 
-/// Matches if the given method declaration declares a member function with an
-/// explicit object parameter.
-///
-/// Given
-/// \code
-/// struct A {
-///  int operator-(this A, int);
-///  void fun(this A &&self);
-///  static int operator()(int);
-///  int operator+(int);
-/// };
-/// \endcode
-///
-/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches 

[clang] [clang][ASTMatchers] Fix forEachArgumentWithParam* for deducing "this" operator calls (PR #84887)

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

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


[clang] [clang-tools-extra] [flang] [lld] [llvm] [flang][clang] Add Visibility specific help text for options (PR #81869)

2024-03-12 Thread David Spickett via cfe-commits


@@ -3382,10 +3382,19 @@ def fopenmp : Flag<["-"], "fopenmp">, Group,
   HelpText<"Parse OpenMP pragmas and generate parallel code.">;
 def fno_openmp : Flag<["-"], "fno-openmp">, Group,
   Flags<[NoArgumentUnused]>;
+class OpenMPVersionHelp {
+  string str = !strconcat(
+"Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default 
value is ",
+default, " for ", program);
+}
 def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group,
   Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
-  HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). 
Default value is 51 for Clang">;
+  HelpText.str>,
+  HelpTextForVisibilities<[
+HelpTextForVisibility.str>,
+HelpTextForVisibility.str>,

DavidSpickett wrote:

Sure, I can make it `array, char*>>`.

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


[clang] [clang][ASTMatchers] Fix forEachArgumentWithParam* for deducing "this" operator calls (PR #84887)

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

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-03-12 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

`Sema.h` changes look good to me.

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


[clang] [clang][CodeCompletion] Allow debuggers to code-complete reserved identifiers (PR #84891)

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

https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/84891

It is not uncommon for LLDB users to dig into internal implementation details 
of system types (including the STL). LLDB's expression evaluator makes use of 
Clang's code-completion facilities but currently reserved identifeirs are 
filtered out (`clang::Decl`s created in LLDB don't have valid locations, so we 
would also fail to code-complete *any* identifiers with reserved prefixes, not 
just ones from system headers).

This patch permits Clang to code-complete reserved identifiers iff we're in the 
debugger.

The associated LLDB tests: https://github.com/llvm/llvm-project/pull/84890

rdar://124098023

>From 5fad198ae29d0e377ab101a25b15c4a52f6955bc Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Tue, 12 Mar 2024 09:56:58 +
Subject: [PATCH] [clang][CodeCompletion] Allow debuggers to code-complete
 reserved identifiers

It is not uncommon for LLDB users to dig into internal implementation
details of system types (including the STL). LLDB's expression evaluator
makes use of Clang's code-completion facilities but currently reserved
identifeirs are filtered out (`clang::Decl`s created in LLDB don't have
valid locations, so we would also fail to code-complete *any*
identifiers with reserved prefixes, not just ones from system headers).

This patch permits Clang to code-complete reserved identifiers iff
we're in the debugger.
---
 clang/lib/Sema/SemaCodeComplete.cpp   | 4 
 clang/test/CodeCompletion/ordinary-name.c | 7 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index c44be0df9b0a85..18a7f2d98340a3 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -764,6 +764,10 @@ getRequiredQualification(ASTContext &Context, const 
DeclContext *CurContext,
 // Filter out names reserved for the implementation if they come from a
 // system header.
 static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
+  // Debuggers want access to all identifiers, including reserved ones.
+  if (SemaRef.getLangOpts().DebuggerSupport)
+return false;
+
   ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts());
   // Ignore reserved names for compiler provided decls.
   if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid())
diff --git a/clang/test/CodeCompletion/ordinary-name.c 
b/clang/test/CodeCompletion/ordinary-name.c
index c8181a248daa2f..93985619206173 100644
--- a/clang/test/CodeCompletion/ordinary-name.c
+++ b/clang/test/CodeCompletion/ordinary-name.c
@@ -5,6 +5,7 @@ typedef struct t _TYPEDEF;
 void foo() {
   int y;
   // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-1):9 %s -o - | FileCheck -check-prefix=CHECK-CC1 
%s
+  // CHECK-CC1-NOT: __builtin_va_list
   // CHECK-CC1-NOT: __INTEGER_TYPE
   // CHECK-CC1: _Imaginary
   // CHECK-CC1: _MyPrivateType
@@ -15,4 +16,8 @@ void foo() {
   // CHECK-CC1: y
 
   // PR8744
-  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-17):11 %s
+  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-18):11 %s
+  
+  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -fdebugger-support 
-code-completion-at=%s:%(line-15):9 %s -o - | FileCheck -check-prefix=CHECK-DBG 
%s
+  // CHECK-DBG: __builtin_va_list
+  // CHECK-DBG: __INTEGER_TYPE

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


[clang] [clang][CodeCompletion] Allow debuggers to code-complete reserved identifiers (PR #84891)

2024-03-12 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Michael Buch (Michael137)


Changes

It is not uncommon for LLDB users to dig into internal implementation details 
of system types (including the STL). LLDB's expression evaluator makes use of 
Clang's code-completion facilities but currently reserved identifeirs are 
filtered out (`clang::Decl`s created in LLDB don't have valid locations, so we 
would also fail to code-complete *any* identifiers with reserved prefixes, not 
just ones from system headers).

This patch permits Clang to code-complete reserved identifiers iff we're in the 
debugger.

The associated LLDB tests: https://github.com/llvm/llvm-project/pull/84890

rdar://124098023

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaCodeComplete.cpp (+4) 
- (modified) clang/test/CodeCompletion/ordinary-name.c (+6-1) 


``diff
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index c44be0df9b0a85..18a7f2d98340a3 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -764,6 +764,10 @@ getRequiredQualification(ASTContext &Context, const 
DeclContext *CurContext,
 // Filter out names reserved for the implementation if they come from a
 // system header.
 static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
+  // Debuggers want access to all identifiers, including reserved ones.
+  if (SemaRef.getLangOpts().DebuggerSupport)
+return false;
+
   ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts());
   // Ignore reserved names for compiler provided decls.
   if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid())
diff --git a/clang/test/CodeCompletion/ordinary-name.c 
b/clang/test/CodeCompletion/ordinary-name.c
index c8181a248daa2f..93985619206173 100644
--- a/clang/test/CodeCompletion/ordinary-name.c
+++ b/clang/test/CodeCompletion/ordinary-name.c
@@ -5,6 +5,7 @@ typedef struct t _TYPEDEF;
 void foo() {
   int y;
   // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-1):9 %s -o - | FileCheck -check-prefix=CHECK-CC1 
%s
+  // CHECK-CC1-NOT: __builtin_va_list
   // CHECK-CC1-NOT: __INTEGER_TYPE
   // CHECK-CC1: _Imaginary
   // CHECK-CC1: _MyPrivateType
@@ -15,4 +16,8 @@ void foo() {
   // CHECK-CC1: y
 
   // PR8744
-  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-17):11 %s
+  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only 
-code-completion-at=%s:%(line-18):11 %s
+  
+  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -fdebugger-support 
-code-completion-at=%s:%(line-15):9 %s -o - | FileCheck -check-prefix=CHECK-DBG 
%s
+  // CHECK-DBG: __builtin_va_list
+  // CHECK-DBG: __INTEGER_TYPE

``




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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits

https://github.com/Discookie updated 
https://github.com/llvm/llvm-project/pull/84166

>From 704d175fde121edaf962614d8c8d626bf8dbf156 Mon Sep 17 00:00:00 2001
From: Viktor 
Date: Wed, 6 Mar 2024 14:10:44 +
Subject: [PATCH 1/3] [clang][dataflow] Add null-check after dereference
 checker

---
 .../bugprone/BugproneTidyModule.cpp   |   3 +
 .../clang-tidy/bugprone/CMakeLists.txt|   1 +
 .../NullCheckAfterDereferenceCheck.cpp| 171 +
 .../bugprone/NullCheckAfterDereferenceCheck.h |  37 ++
 clang-tools-extra/clangd/TidyProvider.cpp |   3 +-
 .../bugprone/null-check-after-dereference.rst | 162 +
 .../bugprone/null-check-after-dereference.cpp | 330 +
 .../Models/NullPointerAnalysisModel.h | 112 
 .../FlowSensitive/Models/CMakeLists.txt   |   1 +
 .../Models/NullPointerAnalysisModel.cpp   | 625 ++
 .../Analysis/FlowSensitive/CMakeLists.txt |   1 +
 .../NullPointerAnalysisModelTest.cpp  | 332 ++
 12 files changed, 1777 insertions(+), 1 deletion(-)
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/NullCheckAfterDereferenceCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/NullCheckAfterDereferenceCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/bugprone/null-check-after-dereference.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/bugprone/null-check-after-dereference.cpp
 create mode 100644 
clang/include/clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h
 create mode 100644 
clang/lib/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.cpp
 create mode 100644 
clang/unittests/Analysis/FlowSensitive/NullPointerAnalysisModelTest.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index a8a23b045f80bb..ddd708dd513355 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -48,6 +48,7 @@
 #include "NoEscapeCheck.h"
 #include "NonZeroEnumToBoolConversionCheck.h"
 #include "NotNullTerminatedResultCheck.h"
+#include "NullCheckAfterDereferenceCheck.h"
 #include "OptionalValueConversionCheck.h"
 #include "ParentVirtualCallCheck.h"
 #include "PosixReturnCheck.h"
@@ -180,6 +181,8 @@ class BugproneModule : public ClangTidyModule {
 CheckFactories.registerCheck("bugprone-posix-return");
 CheckFactories.registerCheck(
 "bugprone-reserved-identifier");
+CheckFactories.registerCheck(
+"bugprone-null-check-after-dereference");
 CheckFactories.registerCheck(
 "bugprone-shared-ptr-array-mismatch");
 
CheckFactories.registerCheck("bugprone-signal-handler");
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 1cd6fb207d7625..5dbe761cb810e7 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -44,6 +44,7 @@ add_clang_library(clangTidyBugproneModule
   NoEscapeCheck.cpp
   NonZeroEnumToBoolConversionCheck.cpp
   NotNullTerminatedResultCheck.cpp
+  NullCheckAfterDereferenceCheck.cpp
   OptionalValueConversionCheck.cpp
   ParentVirtualCallCheck.cpp
   PosixReturnCheck.cpp
diff --git 
a/clang-tools-extra/clang-tidy/bugprone/NullCheckAfterDereferenceCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/NullCheckAfterDereferenceCheck.cpp
new file mode 100644
index 00..7ef3169cc63863
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/NullCheckAfterDereferenceCheck.cpp
@@ -0,0 +1,171 @@
+//===--- NullCheckAfterDereferenceCheck.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 "NullCheckAfterDereferenceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang::tidy::bugprone {
+
+using ast_matchers::MatchFinder;
+using dataflow::NullCheckAfterDereferenceDia

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

2024-03-12 Thread via cfe-commits

mikaoP wrote:

@alexey-bataev Is it good 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][dataflow] Factor out built-in boolean model into an explicit module. (PR #82950)

2024-03-12 Thread via cfe-commits


@@ -1059,9 +1066,16 @@ void Environment::assume(const Formula &F) {
   DACtx->addFlowConditionConstraint(FlowConditionToken, F);
 }
 
+#if 0
 bool Environment::proves(const Formula &F) const {
   return DACtx->flowConditionImplies(FlowConditionToken, F);
 }
+#else
+bool Environment::proves(const Formula &F) const {
+  auto V = simple_bool_model::getLiteralValue(F, *this);
+  return V.has_value() && *V;

martinboehme wrote:

```suggestion
  return V.value_or(false);
```

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


[clang] [clang][dataflow] Factor out built-in boolean model into an explicit module. (PR #82950)

2024-03-12 Thread via cfe-commits


@@ -1059,9 +1066,16 @@ void Environment::assume(const Formula &F) {
   DACtx->addFlowConditionConstraint(FlowConditionToken, F);
 }
 
+#if 0
 bool Environment::proves(const Formula &F) const {
   return DACtx->flowConditionImplies(FlowConditionToken, F);
 }
+#else
+bool Environment::proves(const Formula &F) const {
+  auto V = simple_bool_model::getLiteralValue(F, *this);
+  return V.has_value() && *V;
+}
+#endif
 
 bool Environment::allows(const Formula &F) const {
   return DACtx->flowConditionAllows(FlowConditionToken, F);

martinboehme wrote:

Wouldn't this also need to be changed? I _think_ this can just do `return 
proves(F);`?

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


[clang] [clang][dataflow] Factor out built-in boolean model into an explicit module. (PR #82950)

2024-03-12 Thread via cfe-commits


@@ -50,29 +50,206 @@ const Environment *StmtToEnvMap::getEnvironment(const Stmt 
&S) const {
   return &State->Env;
 }
 
-static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
-  Environment &Env) {
-  Value *LHSValue = Env.getValue(LHS);
-  Value *RHSValue = Env.getValue(RHS);
+static BoolValue &unpackValue(BoolValue &V, Environment &Env) {
+  if (auto *Top = llvm::dyn_cast(&V)) {
+auto &A = Env.getDataflowAnalysisContext().arena();
+return A.makeBoolValue(A.makeAtomRef(Top->getAtom()));
+  }
+  return V;
+}
 
-  if (LHSValue == RHSValue)
-return Env.getBoolLiteralValue(true);
+static void propagateValue(const Expr &From, const Expr &To, Environment &Env) 
{
+  if (auto *Val = Env.getValue(From))
+Env.setValue(To, *Val);
+}
 
-  if (auto *LHSBool = dyn_cast_or_null(LHSValue))
-if (auto *RHSBool = dyn_cast_or_null(RHSValue))
-  return Env.makeIff(*LHSBool, *RHSBool);
+static void propagateStorageLocation(const Expr &From, const Expr &To,
+ Environment &Env) {
+  if (auto *Loc = Env.getStorageLocation(From))
+Env.setStorageLocation(To, *Loc);
+}
+
+// Propagates the value or storage location of `From` to `To` in cases where
+// `From` may be either a glvalue or a prvalue. `To` must be a glvalue iff
+// `From` is a glvalue.
+static void propagateValueOrStorageLocation(const Expr &From, const Expr &To,
+Environment &Env) {
+  assert(From.isGLValue() == To.isGLValue());
+  if (From.isGLValue())
+propagateStorageLocation(From, To, Env);
+  else
+propagateValue(From, To, Env);
+}
 
+namespace sat_bool_model {
+
+BoolValue &freshBoolValue(Environment &Env) {
   return Env.makeAtomicBoolValue();
 }
 
-static BoolValue &unpackValue(BoolValue &V, Environment &Env) {
-  if (auto *Top = llvm::dyn_cast(&V)) {
-auto &A = Env.getDataflowAnalysisContext().arena();
-return A.makeBoolValue(A.makeAtomRef(Top->getAtom()));
+BoolValue &rValueFromLValue(BoolValue &V, Environment &Env) {
+  return unpackValue(V, Env);
+}
+
+BoolValue &logicalOrOp(BoolValue &LHS, BoolValue &RHS, Environment &Env) {
+  return Env.makeOr(LHS, RHS);
+}
+
+BoolValue &logicalAndOp(BoolValue &LHS, BoolValue &RHS, Environment &Env) {
+  return Env.makeAnd(LHS, RHS);
+}
+
+BoolValue &eqOp(BoolValue &LHS, BoolValue &RHS, Environment &Env) {
+  return Env.makeIff(LHS, RHS);
+}
+
+BoolValue &neOp(BoolValue &LHS, BoolValue &RHS, Environment &Env) {
+  return Env.makeNot(Env.makeIff(LHS, RHS));
+}
+
+BoolValue ¬Op(BoolValue &Sub, Environment &Env) { return Env.makeNot(Sub); }
+
+void transferBranch(bool BranchVal, BoolValue &CondVal, Environment &Env) {
+  // The condition must be inverted for the successor that encompasses the
+  // "else" branch, if such exists.
+  BoolValue &AssertedVal = BranchVal ? CondVal : Env.makeNot(CondVal);
+  Env.assume(AssertedVal.formula());
+}
+
+} // namespace sat_bool_model
+
+namespace simple_bool_model {
+
+std::optional getLiteralValue(const Formula &F, const Environment &Env) {
+  switch (F.kind()) {
+  case Formula::AtomRef:
+return Env.getAtomValue(F.getAtom());
+  case Formula::Literal:
+return F.literal();
+  case Formula::Not: {

martinboehme wrote:

Why do we need this case? Is it not covered by `neOp()` above? (I.e. are there 
ever any cases where we actually have `Formula::Not` formulas?)

If we do need this, don't we also need corresponding cases for `Formula::And` 
and `Formula::Or`?

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


[clang] [clang][Sema] Track trivial-relocatability as a type trait (PR #84621)

2024-03-12 Thread Amirreza Ashouri via cfe-commits

https://github.com/AMP999 updated 
https://github.com/llvm/llvm-project/pull/84621

>From 6e127e5794efafaabf82b6c3d5e0634ddcfee977 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Sat, 2 Mar 2024 15:37:33 +0330
Subject: [PATCH 1/2] [clang][Sema] Track trivial-relocatability as a type
 trait

To resolve llvm#69394, this patch separates trivial-relocatability's logic from 
`canPassInRegisters` to decide if a type is trivial-relocatable. A type passed 
in registers doesn't necessarily mean trivial-relocatability of that type(e.g. 
on Windows) i.e. it gives us an unintended false positive. This change would be 
beneficial for Abseil since they rely upon these semantics.
By these changes now:
User-provided special members prevent natural trivial-relocatabilitiy.
It's important because Abseil and maybe others assume the assignment 
operator doesn't have an impact on the trivial-relocatability of a type.
In fact, it does have an effect, and with a user-provided assignment 
operator, the compiler should only accept it as trivial-relocatable if it's 
implied by the `[[clang::trivial_abi]]` attribute.
Just because a type can pass in registers doesn't necessarily mean it's 
trivial-relocatable.
The `[[clang::trivial_abi]]` attribute always implies trivial-relocatability, 
even if it can't pass in registers.
The trait has extensive tests for both old and new behaviors. Test aggregation 
of
both kinds of types as data members; inheritance; virtual member functions
and virtual bases; const and reference data members; and reference types.

Fixes llvm#69394
---
 .../clang/AST/CXXRecordDeclDefinitionBits.def |   5 +
 clang/include/clang/AST/DeclCXX.h |   3 +
 clang/lib/AST/DeclCXX.cpp |  45 +++-
 clang/lib/AST/Type.cpp|   4 +-
 clang/test/SemaCXX/attr-trivial-abi.cpp   |  35 --
 .../test/SemaCXX/is-trivially-relocatable.cpp | 106 ++
 clang/test/SemaCXX/type-traits.cpp|  56 +
 7 files changed, 214 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaCXX/is-trivially-relocatable.cpp

diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def 
b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index cdf0804680ad0a..36d3cfb7dfe85b 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -189,6 +189,11 @@ FIELD(DeclaredNonTrivialSpecialMembers, 6, MERGE_OR)
 /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
 FIELD(DeclaredNonTrivialSpecialMembersForCall, 6, MERGE_OR)
 
+/// True when this class's bases and fields are all trivially relocatable
+/// or references, and the class itself has no user-provided special
+/// member functions.
+FIELD(IsNaturallyTriviallyRelocatable, 1, NO_MERGE)
+
 /// True when this class has a destructor with no semantic effect.
 FIELD(HasIrrelevantDestructor, 1, NO_MERGE)
 
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..a58126c98597b0 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1386,6 +1386,9 @@ class CXXRecordDecl : public RecordDecl {
 (SMF_CopyConstructor | SMF_MoveConstructor | SMF_Destructor);
   }
 
+  /// Determine whether this class is trivially relocatable
+  bool isTriviallyRelocatable() const;
+
   /// Determine whether declaring a const variable with this type is ok
   /// per core issue 253.
   bool allowConstDefaultInit() const {
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 1c3dcf63465c68..5cd1e6d8d720ef 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -95,7 +95,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl 
*D)
   DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
   HasTrivialSpecialMembersForCall(SMF_All),
   DeclaredNonTrivialSpecialMembers(0),
-  DeclaredNonTrivialSpecialMembersForCall(0), 
HasIrrelevantDestructor(true),
+  DeclaredNonTrivialSpecialMembersForCall(0),
+  IsNaturallyTriviallyRelocatable(true), HasIrrelevantDestructor(true),
   HasConstexprNonCopyMoveConstructor(false),
   HasDefaultedDefaultConstructor(false),
   DefaultedDefaultConstructorIsConstexpr(true),
@@ -279,6 +280,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
 
   //   An aggregate is a class with [...] no virtual functions.
   data().Aggregate = false;
+
+  // A trivially relocatable class is a class:
+  // -- which has no virtual member functions or virtual base classes
+  data().IsNaturallyTriviallyRelocatable = false;
 }
 
 // C++0x [class]p7:
@@ -293,6 +298,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
 if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
   data().HasNonLiteralTypeFieldsOrBases = true;
 
+if (Base->isVirtual()

[clang] [clang][Sema] Track trivial-relocatability as a type trait (PR #84621)

2024-03-12 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 3358838446428976a41390fde98fe5b04b08a132 
a7ff71da99cd158e9bc608b43577cb854dfc7fae -- 
clang/test/SemaCXX/is-trivially-relocatable.cpp 
clang/include/clang/AST/DeclCXX.h clang/lib/AST/DeclCXX.cpp 
clang/lib/AST/Type.cpp clang/test/SemaCXX/attr-trivial-abi.cpp 
clang/test/SemaCXX/type-traits.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 5811e746b0..a800d611fd 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -885,7 +885,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
   SMKind |= SMF_MoveAssignment;
 }
 
-if (Method->isUserProvided() && (Method->isCopyAssignment() || 
Method->isMoveAssignment()))
+if (Method->isUserProvided() &&
+(Method->isCopyAssignment() || Method->isMoveAssignment()))
   data().IsNaturallyTriviallyRelocatable = false;
 
 // Keep the list of conversion functions up-to-date.

``




https://github.com/llvm/llvm-project/pull/84621
___
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-12 Thread Alexey Bataev via cfe-commits

alexey-bataev wrote:

Yes, as it was before :) no need to wait for another lgtm.

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][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits

https://github.com/martinboehme requested changes to this pull request.


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


[clang] [clang][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits

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


[clang] [clang][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits


@@ -337,26 +274,33 @@ computeBlockInputState(const CFGBlock &Block, 
AnalysisContext &AC) {
 AC.BlockStates[Pred->getBlockID()];
 if (!MaybePredState)
   continue;
-
-if (AC.Analysis.builtinOptions()) {
-  if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {
-// We have a terminator: we need to mutate an environment to describe
-// when the terminator is taken. Copy now.
+const TypeErasedDataflowAnalysisState &PredState = *MaybePredState;
+
+if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {
+  bool BranchVal = blockIndexInPredecessor(*Pred, Block) == 0;

martinboehme wrote:

Move this down to the point where it's actually needed (this is included in the 
suggestion above).

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


[clang] [clang][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits


@@ -64,88 +62,27 @@ static bool isBackedgeNode(const CFGBlock &B) {
 
 namespace {
 
-// The return type of the visit functions in TerminatorVisitor. The first
-// element represents the terminator expression (that is the conditional
-// expression in case of a path split in the CFG). The second element
-// represents whether the condition was true or false.
-using TerminatorVisitorRetTy = std::pair;
-
-/// Extends the flow condition of an environment based on a terminator
-/// statement.
+/// Extracts the condition expression.

martinboehme wrote:

```suggestion
/// Extracts the terminator condition expression.
```

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


[clang] [clang][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits


@@ -337,26 +274,33 @@ computeBlockInputState(const CFGBlock &Block, 
AnalysisContext &AC) {
 AC.BlockStates[Pred->getBlockID()];
 if (!MaybePredState)
   continue;
-
-if (AC.Analysis.builtinOptions()) {
-  if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {
-// We have a terminator: we need to mutate an environment to describe
-// when the terminator is taken. Copy now.
+const TypeErasedDataflowAnalysisState &PredState = *MaybePredState;
+
+if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {

martinboehme wrote:

To make this clearer, here's how the whole code block could be changed to make 
it (IMO) simpler (I can't do this as a suggested edit because I would have to 
include deleted lines in the block of code, and github doesn't allow me to do 
this):

```cxx
const Expr *TerminatorCond = 
getTerminatorCondition(Pred->getTerminatorStmt());
if (TerminatorCond == nullptr) {
  Builder.addUnowned(PredState);
  continue;
}

bool BranchVal = blockIndexInPredecessor(*Pred, Block) == 0;

// `transferBranch` may need to mutate the environment to describe the
// dynamic effect of the terminator for a given branch.  Copy now.
TypeErasedDataflowAnalysisState Copy = PredState.fork();
if (AC.Analysis.builtinOptions()) {
  auto *CondVal = Copy.Env.get(*TerminatorCond);
  // In transferCFGBlock(), we ensure that we always have a `Value`
  // for the terminator condition, so assert this. We consciously
  // assert ourselves instead of asserting via `cast()` so that we get
  // a more meaningful line number if the assertion fails.
  assert(CondVal != nullptr);
  BoolValue *AssertedVal =
  BranchVal ? CondVal : &Copy.Env.makeNot(*CondVal);
  Copy.Env.assume(AssertedVal->formula());
}
AC.Analysis.transferBranchTypeErased(BranchVal, TerminatorCond, 
Copy.Lattice,
 Copy.Env);
Builder.addOwned(std::move(Copy));
```

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


[clang] [clang][dataflow] Refactor processing of terminator element (PR #84499)

2024-03-12 Thread via cfe-commits


@@ -337,26 +274,33 @@ computeBlockInputState(const CFGBlock &Block, 
AnalysisContext &AC) {
 AC.BlockStates[Pred->getBlockID()];
 if (!MaybePredState)
   continue;
-
-if (AC.Analysis.builtinOptions()) {
-  if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {
-// We have a terminator: we need to mutate an environment to describe
-// when the terminator is taken. Copy now.
+const TypeErasedDataflowAnalysisState &PredState = *MaybePredState;
+
+if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {

martinboehme wrote:

I'd suggest doing the shorter case first, so this longer case can be indented 
less:

```cxx
  const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt();
  if (PredTerminatorStmt == nullptr) {
Builder.addUnowned(PredState);
continue;
  }
```

Even better, introduce a short function `getTerminatorCondition()` that can 
handle a null argument:

```cxx
const Expr *getTerminatorCondition(const Stmt *TerminatorStmt) {
  if (TerminatorStmt == nullptr) return nullptr;
  return TerminatorVisitor().Visit(TerminatorStmt);
}
```

Then you can do this:

```cxx
  const Expr *TerminatorCond = 
getTerminatorCondition(Pred->getTerminatorStmt());
  if (TerminatorCond == nullptr) {
Builder.addUnowned(PredState);
continue;
  }
```

https://github.com/llvm/llvm-project/pull/84499
___
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-12 Thread Axel Lundberg via cfe-commits


@@ -5571,11 +5571,52 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
   break;
 }
 
-RValue RV = EmitAnyExpr(E->getRHS());
+llvm::Value *Previous = nullptr;

Zonotora wrote:

I would also like to have it work similar to how EmitCompoundAssignmentLValue 
works, however it doesn't seem completely trivial to make this change? Maybe it 
is better suited in its own PR as well? But I can definitely convert:
```cpp
if (E->getLHS()->refersToBitField()) {
  // Get the RHS before scalar conversion.
  if (auto *ICE = GetOriginalRHSForBitfieldAssignment(E)) {
SrcType = ICE->getSubExpr()->getType();
Previous = EmitScalarExpr(ICE->getSubExpr());
// Pass default ScalarConversionOpts to avoid emitting
// integer sanitizer checks as E refers to bitfield.
llvm::Value *RHS = EmitScalarConversion(
Previous, SrcType, ICE->getType(), ICE->getExprLoc());
RV = RValue::get(RHS);
  }
}
```
to something like:
```cpp
if (E->getLHS()->refersToBitField())
  Previous = EmitForOriginalRHSBitfieldAssignment(E, &RHS));
```
to at least de-duplicate some parts of it...

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] [llvm] [Clang][BPF] Allow sign extension for int type call parameters (PR #84874)

2024-03-12 Thread Pu Lehui via cfe-commits

pulehui wrote:

Thanks Yonghong. It works through the kfunc_call case in no_alu32 mode, as well 
as other cases in riscv64.
Tested-by: Pu Lehui 

https://github.com/llvm/llvm-project/pull/84874
___
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-12 Thread Axel Lundberg via cfe-commits


@@ -5571,11 +5571,52 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
   break;
 }
 
-RValue RV = EmitAnyExpr(E->getRHS());
+llvm::Value *Previous = nullptr;
+RValue RV;
+QualType SrcType = E->getRHS()->getType();
+// Check if LHS is a bitfield, if RHS contains an implicit cast expression
+// we want to extract that value and potentially (if the bitfield sanitizer
+// is enabled) use it to check for an implicit conversion.
+if (E->getLHS()->refersToBitField()) {
+  // Get the RHS before scalar conversion.
+  if (auto *ICE = GetOriginalRHSForBitfieldSanitizer(E)) {

Zonotora wrote:

Will do!

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] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)

2024-03-12 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:

> Do we even have initial PTUs in the default case?

Well, this test passes, if I comment out the for loop in the ctor that executes 
initial PTUs:
https://github.com/llvm/llvm-project/pull/84758/files#diff-b8484f1fc5b057f146ed5d9b6e2cd47c3f6f5ae879c7a0eee44f0a272581a88cR250-R254

> Also the minimal reproducer shows a more general version where the virtual 
> destructor is actually defined inline 
> (https://github.com/llvm/llvm-project/commit/c861d32d7c2791bdc058d9d9fbaecc1c2f07b8c7
>  addresses the case where it is out-of-line, which is special due to key 
> virtual functions).

Oh that's a good note, I had not considered the difference yet and actually 
they have different backtraces. Eventually, they both reach the same VTablePtr 
code though.

> I could not see the stack trace on osx. Can you paste it here?

Here is a diff (inline left, out-of-line right):
https://github.com/llvm/llvm-project/assets/7307454/41b64f92-83ea-4f82-b983-0b05e32ace42";>

> So if that breaks entirely (which is critical for us), I'm personally not ok 
> with just `XFAIL`ing it to land another change...

What breaks here is the parser and this patch doesn't even touch it. Not sure I 
am missing something, but it seems that it triggers a bug that always existed 
and just didn't show up so far.

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] eb31970 - Add bit-precise overloads for builtin operators (#84755)

2024-03-12 Thread via cfe-commits

Author: Aaron Ballman
Date: 2024-03-12T07:40:27-04:00
New Revision: eb319708dc5371bc560c301742abcf94cc5b3de5

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

LOG: Add bit-precise overloads for builtin operators  (#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

Added: 
clang/test/SemaCXX/overload-bitint.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaOverload.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88e552d5c46113..4a08b78d78b69b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -265,6 +265,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..f6bd85bdc64692 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.
@@ -8913,7 +8920,7 @@ class BuiltinOperatorOverloadBuilder {
   SmallVectorImpl &CandidateTypes;
   OverloadCandidateSet &CandidateSet;
 
-  static constexpr int ArithmeticTypesCap = 24;
+  static constexpr int ArithmeticTypesCap = 26;
   SmallVector ArithmeticTypes;
 
   // Define some indices used to iterate over the arithmetic types in
@@ -8955,6 +8962,20 @@ class BuiltinOperatorOverloadBuilder {
 (S.Context.getAuxTargetInfo() &&
  S.Context.getAuxTargetInfo()->hasInt128Type()))
   ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+
+/// We 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
+/// 
diff erent sets, we need to do some extra work to unique things. Insert
+/// the candidates into a unique set, then move 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::move(BitIntCandidates, std::back_inserter(ArithmeticTypes));
 LastPromotedIntegralType = ArithmeticTypes.size();
 LastPromotedArithmeticType = ArithmeticTypes.size();
 // End of promoted types.
@@ -8975,7 +8996,11 @@ class BuiltinOperatorOverloadBuilder {
 // End of integral types.
 // FIXME: What about complex? What about half?
 
-assert(ArithmeticTypes.size() <= ArithmeticTypesCap &&
+// We don't know for sure how many bit-precise candidates were involved, so
+// we subtract those from the total when testing whether we're under the
+// cap or not.
+assert(ArithmeticTypes.size() - BitIntCandidates.size() <=
+   ArithmeticTypesCap &&
"Enough inline storage for all arithmetic 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"
+
+st

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

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

https://github.com/AaronBallman closed 
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] [clang] Fix OMPT ident flag in combined distribute parallel for pragma (PR #80987)

2024-03-12 Thread via cfe-commits

mikaoP wrote:

I have no permissions to do the merge. Could anyone do it?

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-repl] Set up executor implicitly to account for init PTUs (PR #84758)

2024-03-12 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:

Let me share some more observations.

We **execute** the initial PTU and not only parse it. It shouldn't make a 
difference for the parser right? Still, I wasn't sure, especially since we 
unusally **only parse** runtime PTUs. So I made some experiments:
```
Init  Runtime  Dtor-def  |  New Delete  Automatic
(1) Execute   Execute   Out-of-line  |  fails   -   fails
 Inline  |  fails   -   once*

(2) Execute   Parse Out-of-line  |  fails   -   fails
 Inline  |  once*   fails   once

(3) Parse Any   Out-of-line  |  works   works   works
 Inline  |  works   works   works
```

Without `-O2` everything works.
Automatic = `A a1(1);`
`once` = Works exactly once (including shutdown)
`once*` = Same, but only if dtor has side-effects e.g. printf call

(1) is the behavior with this patch. (3) was the status-quo before this patch.

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-12 Thread Vassil Vassilev via cfe-commits
Stefan =?utf-8?q?Gränitz?= 
Message-ID:
In-Reply-To: 



@@ -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);

vgvassilev wrote:

Thanks for the detailed analysis. @hahnjo can we “rent” some of your brain here 
to save us quite some debugging ;) ?

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] Fix OMPT ident flag in combined distribute parallel for pragma (PR #80987)

2024-03-12 Thread Alexey Bataev via cfe-commits

https://github.com/alexey-bataev closed 
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] Emit bad shift warnings (PR #70307)

2024-03-12 Thread Budimir Aranđelović via cfe-commits

budimirarandjelovicsyrmia wrote:

Ping @AaronBallman 

https://github.com/llvm/llvm-project/pull/70307
___
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-12 Thread Vassil Vassilev via cfe-commits
Stefan =?utf-8?q?Gränitz?= 
Message-ID:
In-Reply-To: 



@@ -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);

vgvassilev wrote:

I remember we needed to do something to swap the tbaa analysis in codegen 
across ptus. 

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] Emit bad shift warnings (PR #70307)

2024-03-12 Thread Timm Baeder via cfe-commits

tbaederr wrote:

There are two questions above about removing a diagnostic that you haven't 
answered yet

https://github.com/llvm/llvm-project/pull/70307
___
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-12 Thread Stefan Gränitz via cfe-commits

https://github.com/weliveindetail updated 
https://github.com/llvm/llvm-project/pull/84460

From a8c9cf8901d3fc24f3a2c2161b4a8796a7b28989 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= 
Date: Thu, 7 Mar 2024 23:04:22 +0100
Subject: [PATCH] [clang-repl] Expose CreateExecutor() and ResetExecutor() in
 extended Interpreter interface

---
 clang/include/clang/Interpreter/Interpreter.h |  9 ++-
 clang/lib/Interpreter/Interpreter.cpp |  6 +
 clang/unittests/Interpreter/CMakeLists.txt|  1 +
 .../Interpreter/InterpreterExtensionsTest.cpp | 24 +++
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 469ce1fd75bf84..1dcba1ef967980 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -96,7 +96,6 @@ class Interpreter {
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
-  llvm::Error CreateExecutor();
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -114,6 +113,14 @@ class Interpreter {
   // That's useful for testing and out-of-tree clients.
   Interpreter(std::unique_ptr CI, llvm::Error &Err);
 
+  // Create the internal IncrementalExecutor, or re-create it after calling
+  // ResetExecutor().
+  llvm::Error CreateExecutor();
+
+  // Delete the internal IncrementalExecutor. This causes a hard shutdown of 
the
+  // JIT engine. In particular, it doesn't run cleanup or destructors.
+  void ResetExecutor();
+
   // 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
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e293fefb524963..7fa52f2f15fc49 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -375,6 +375,10 @@ Interpreter::Parse(llvm::StringRef Code) {
 llvm::Error Interpreter::CreateExecutor() {
   const clang::TargetInfo &TI =
   getCompilerInstance()->getASTContext().getTargetInfo();
+  if (IncrExecutor)
+return llvm::make_error("Operation failed. "
+   "Execution engine exists",
+   std::error_code());
   llvm::Error Err = llvm::Error::success();
   auto Executor = std::make_unique(*TSCtx, Err, TI);
   if (!Err)
@@ -383,6 +387,8 @@ llvm::Error Interpreter::CreateExecutor() {
   return Err;
 }
 
+void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
+
 llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
   assert(T.TheModule);
   if (!IncrExecutor) {
diff --git a/clang/unittests/Interpreter/CMakeLists.txt 
b/clang/unittests/Interpreter/CMakeLists.txt
index 046d96ad0ec644..498070b43d922e 100644
--- a/clang/unittests/Interpreter/CMakeLists.txt
+++ b/clang/unittests/Interpreter/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
   OrcJIT
   Support
   TargetParser
+  TestingSupport
   )
 
 add_clang_unittest(ClangReplInterpreterTests
diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp 
b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
index 4e9f2dba210a37..f1c3d65ab0a95d 100644
--- a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
@@ -27,6 +27,30 @@
 using namespace clang;
 namespace {
 
+class TestCreateResetExecutor : public Interpreter {
+public:
+  TestCreateResetExecutor(std::unique_ptr CI,
+  llvm::Error &Err)
+  : Interpreter(std::move(CI), Err) {}
+
+  llvm::Error testCreateExecutor() { return Interpreter::CreateExecutor(); }
+
+  void resetExecutor() { Interpreter::ResetExecutor(); }
+};
+
+TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
+  clang::IncrementalCompilerBuilder CB;
+  llvm::Error ErrOut = llvm::Error::success();
+  TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut);
+  cantFail(std::move(ErrOut));
+  cantFail(Interp.testCreateExecutor());
+  Interp.resetExecutor();
+  cantFail(Interp.testCreateExecutor());
+  EXPECT_THAT_ERROR(Interp.testCreateExecutor(),
+llvm::FailedWithMessage("Operation failed. "
+"Execution engine exists"));
+}
+
 class RecordRuntimeIBMetrics : public Interpreter {
   struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
 NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {}

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

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

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

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

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

The precommit CI failure is not an actual issue, so LGTM with a suggestion for 
the release note. Thank you for this!

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

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


@@ -192,6 +192,8 @@ Removed Compiler Flags
 Attribute Changes in Clang
 --
 
+- Added support for the `[[omp::assume]]` attribute.

AaronBallman wrote:

This should probably go under an OpenMP-specific section as it relates more to 
OpenMP than anything else.

https://github.com/llvm/llvm-project/pull/84582
___
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-12 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,Balazs Benics
 ,NagyDonat 
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/5] [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/5] 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 n

[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

2024-03-12 Thread via cfe-commits


@@ -192,6 +192,8 @@ Removed Compiler Flags
 Attribute Changes in Clang
 --
 
+- Added support for the `[[omp::assume]]` attribute.

Sirraide wrote:

> This should probably go under an OpenMP-specific section as it relates more 
> to OpenMP than anything else.

Should I add an omp-specific section to the Clang release notes? Because there 
doesn’t seem to be one, and the OpenMP release notes in the `openmp` directory 
are specifically meant for changes to the runtime—at least according to a 
comment there.

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tobias Hieta via cfe-commits

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tobias Hieta via cfe-commits

https://github.com/tru commented:

Thanks for working on documentation!

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tobias Hieta via cfe-commits


@@ -2410,20 +2410,35 @@ usual build cycle when using sample profilers for 
optimization:
 
 1. Build the code with source line table information. You can use all the
usual build flags that you always build your application with. The only
-   requirement is that you add ``-gline-tables-only`` or ``-g`` to the
-   command line. This is important for the profiler to be able to map
-   instructions back to source line locations.
+   requirement is that DWARF debug info including source line information is
+   generated. This DWARF information is important for the profiler to be able
+   to map instructions back to source line locations.
+
+   On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
 
.. code-block:: console
 
  $ clang++ -O2 -gline-tables-only code.cc -o code
 
+   It is also possible to include DWARF in Windows binaries:

tru wrote:

Maybe this should be worded that while codeview is the standard on Windows, you 
can use DWARF instead.

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tobias Hieta via cfe-commits


@@ -2410,20 +2410,35 @@ usual build cycle when using sample profilers for 
optimization:
 
 1. Build the code with source line table information. You can use all the
usual build flags that you always build your application with. The only
-   requirement is that you add ``-gline-tables-only`` or ``-g`` to the
-   command line. This is important for the profiler to be able to map
-   instructions back to source line locations.
+   requirement is that DWARF debug info including source line information is
+   generated. This DWARF information is important for the profiler to be able
+   to map instructions back to source line locations.
+
+   On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
 
.. code-block:: console
 
  $ clang++ -O2 -gline-tables-only code.cc -o code
 
+   It is also possible to include DWARF in Windows binaries:
+
+   .. code-block:: console
+
+ $ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld 
-link -debug:dwarf
+
 2. Run the executable under a sampling profiler. The specific profiler
you use does not really matter, as long as its output can be converted
-   into the format that the LLVM optimizer understands. Currently, there
-   exists a conversion tool for the Linux Perf profiler
-   (https://perf.wiki.kernel.org/), so these examples assume that you
-   are using Linux Perf to profile your code.
+   into the format that the LLVM optimizer understands.
+
+   Two such profilers are the the Linux Perf profiler
+   (https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),

tru wrote:

I think we can make it clear that perf is only on Linux while SEP is Linux and 
Windows.

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tobias Hieta via cfe-commits


@@ -2410,20 +2410,35 @@ usual build cycle when using sample profilers for 
optimization:
 
 1. Build the code with source line table information. You can use all the
usual build flags that you always build your application with. The only
-   requirement is that you add ``-gline-tables-only`` or ``-g`` to the
-   command line. This is important for the profiler to be able to map
-   instructions back to source line locations.
+   requirement is that DWARF debug info including source line information is
+   generated. This DWARF information is important for the profiler to be able
+   to map instructions back to source line locations.
+
+   On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
 
.. code-block:: console
 
  $ clang++ -O2 -gline-tables-only code.cc -o code
 
+   It is also possible to include DWARF in Windows binaries:
+
+   .. code-block:: console
+
+ $ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld 
-link -debug:dwarf
+
 2. Run the executable under a sampling profiler. The specific profiler
you use does not really matter, as long as its output can be converted
-   into the format that the LLVM optimizer understands. Currently, there
-   exists a conversion tool for the Linux Perf profiler
-   (https://perf.wiki.kernel.org/), so these examples assume that you
-   are using Linux Perf to profile your code.
+   into the format that the LLVM optimizer understands.
+
+   Two such profilers are the the Linux Perf profiler
+   (https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),
+   available as part of `Intel VTune
+   
`_.
+
+   The LLVM tool ``llvm-profgen`` can convert output of either Perf or SEP. An
+   external tool, AutoFDO, also supports Linux Perf output.

tru wrote:

maybe link to AutoFDO or explain what it's used for here?

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Martin Storsjö via cfe-commits


@@ -2410,20 +2410,35 @@ usual build cycle when using sample profilers for 
optimization:
 
 1. Build the code with source line table information. You can use all the
usual build flags that you always build your application with. The only
-   requirement is that you add ``-gline-tables-only`` or ``-g`` to the
-   command line. This is important for the profiler to be able to map
-   instructions back to source line locations.
+   requirement is that DWARF debug info including source line information is
+   generated. This DWARF information is important for the profiler to be able
+   to map instructions back to source line locations.
+
+   On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
 
.. code-block:: console
 
  $ clang++ -O2 -gline-tables-only code.cc -o code
 
+   It is also possible to include DWARF in Windows binaries:

mstorsjo wrote:

Codeview is the standard in MSVC style environments, while DWARF is the 
standard in MinGW too.

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

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


@@ -192,6 +192,8 @@ Removed Compiler Flags
 Attribute Changes in Clang
 --
 
+- Added support for the `[[omp::assume]]` attribute.

AaronBallman wrote:

I'd recommend adding a section to clang's release notes for OpenMP in that case.

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

2024-03-12 Thread via cfe-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/84582

>From d436f7fefb967f050220a8ede6d05c8e26f363b3 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Fri, 8 Mar 2024 23:54:14 +0100
Subject: [PATCH 1/4] [Clang] [Parser] Support [[omp::assume]]

---
 clang/include/clang/Basic/Attr.td |  2 +-
 clang/lib/Basic/Attributes.cpp|  8 ++--
 clang/lib/Parse/ParseDeclCXX.cpp  |  4 +++-
 clang/test/Sema/attr-assume.c | 17 +
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index fa191c7378dba4..c6877b61fa7f1e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4144,7 +4144,7 @@ def OMPDeclareVariant : InheritableAttr {
 }
 
 def Assumption : InheritableAttr {
-  let Spellings = [Clang<"assume">];
+  let Spellings = [Clang<"assume">, CXX11<"omp", "assume">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
   let InheritEvenIfAlreadyPresent = 1;
   let Documentation = [AssumptionDocs];
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 44a4f1890d39e1..867d241a2cf847 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -47,8 +47,12 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
   // attributes. We support those, but not through the typical attribute
   // machinery that goes through TableGen. We support this in all OpenMP modes
   // so long as double square brackets are enabled.
-  if (LangOpts.OpenMP && ScopeName == "omp")
-return (Name == "directive" || Name == "sequence") ? 1 : 0;
+  //
+  // Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the
+  // regular attribute parsing machinery.
+  if (LangOpts.OpenMP && ScopeName == "omp" &&
+  (Name == "directive" || Name == "sequence"))
+return 1;
 
   int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);
   if (res)
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 62632b2d79792e..64129d7eaface5 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4579,7 +4579,9 @@ bool Parser::ParseCXX11AttributeArgs(
 return true;
   }
 
-  if (ScopeName && ScopeName->isStr("omp")) {
+  // [[omp::directive]] and [[omp::sequence]] need special handling.
+  if (ScopeName && ScopeName->isStr("omp") &&
+  (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {
 Diag(AttrNameLoc, getLangOpts().OpenMP >= 51
   ? diag::warn_omp51_compat_attributes
   : diag::ext_omp_attributes);
diff --git a/clang/test/Sema/attr-assume.c b/clang/test/Sema/attr-assume.c
index 98deffa3a74609..3b7721647dee60 100644
--- a/clang/test/Sema/attr-assume.c
+++ b/clang/test/Sema/attr-assume.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -fopenmp -DCXX -verify %s
 
+#ifndef CXX
 void f1(void) __attribute__((assume(3))); // expected-error {{expected string 
literal as argument of 'assume' attribute}}
 void f2(void) __attribute__((assume(int))); // expected-error {{expected 
string literal as argument of 'assume' attribute}}
 void f3(void) __attribute__((assume(for))); // expected-error {{expected 
string literal as argument of 'assume' attribute}}
@@ -12,3 +14,18 @@ void f9(void) __attribute__((assume("omp_no_openmp", 
"omp_no_openmp"))); // expe
 
 int g1 __attribute__((assume(0))); // expected-error {{expected string literal 
as argument of 'assume' attribute}}
 int g2 __attribute__((assume("omp_no_openmp"))); // expected-warning 
{{'assume' attribute only applies to functions and Objective-C methods}}
+
+#else
+[[omp::assume(3)]] void f1(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume(int)]] void f2(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume(for)]] void f3(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume("")]] void f4(); // expected-warning {{unknown assumption 
string ''; attribute is potentially ignored}}
+[[omp::assume("omp_no_openmp")]] void f5();
+[[omp::assume("omp_noopenmp")]] void f6(); // expected-warning {{unknown 
assumption string 'omp_noopenmp' may be misspelled; attribute is potentially 
ignored, did you mean 'omp_no_openmp'?}}
+[[omp::assume("omp_no_openmp_routine")]] void f7(); // expected-warning 
{{unknown assumption string 'omp_no_openmp_routine' may be misspelled; 
attribute is potentially ignored, did you mean 'omp_no_openmp_routines'?}}
+[[omp::assume("omp_no_openmp1")]] void f8(); // expected-warning {{unknown 
assumption string 'omp_no_openmp1' may be misspelled; attribute is potentially 
ignored, did you mean 'omp_no_openmp'?}}
+[[omp::assume("omp_no_openmp", "omp_no_openmp")]] void f9(); // expected-err

[clang] b5a16b6 - [Clang] [Parser] Support [[omp::assume]] (#84582)

2024-03-12 Thread via cfe-commits

Author: Sirraide
Date: 2024-03-12T13:42:43+01:00
New Revision: b5a16b6d8ad51df7c14cd696f3dc1f98b6984905

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

LOG: [Clang] [Parser] Support [[omp::assume]] (#84582)

This pr implements the `[[omp::assume]]` spelling for the 
`__attribute__((assume))` attribute. It does not change anything about how that 
attribute is handled by the rest of Clang.

Added: 
clang/test/OpenMP/attr-assume.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/lib/Basic/Attributes.cpp
clang/lib/Parse/ParseDeclCXX.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4a08b78d78b69b..6c30af304d981d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -500,6 +500,11 @@ Python Binding Changes
 
 - Exposed `CXRewriter` API as `class Rewriter`.
 
+OpenMP Support
+--
+
+- Added support for the `[[omp::assume]]` attribute.
+
 Additional Information
 ==
 

diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index fd7970d0451acd..080340669b60a0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4159,7 +4159,7 @@ def OMPDeclareVariant : InheritableAttr {
 }
 
 def OMPAssume : InheritableAttr {
-  let Spellings = [Clang<"assume">];
+  let Spellings = [Clang<"assume">, CXX11<"omp", "assume">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
   let InheritEvenIfAlreadyPresent = 1;
   let Documentation = [OMPAssumeDocs];

diff  --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 44a4f1890d39e1..867d241a2cf847 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -47,8 +47,12 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
   // attributes. We support those, but not through the typical attribute
   // machinery that goes through TableGen. We support this in all OpenMP modes
   // so long as double square brackets are enabled.
-  if (LangOpts.OpenMP && ScopeName == "omp")
-return (Name == "directive" || Name == "sequence") ? 1 : 0;
+  //
+  // Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the
+  // regular attribute parsing machinery.
+  if (LangOpts.OpenMP && ScopeName == "omp" &&
+  (Name == "directive" || Name == "sequence"))
+return 1;
 
   int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);
   if (res)

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp 
b/clang/lib/Parse/ParseDeclCXX.cpp
index bdca10c4c7c0b4..77d2382ea6d907 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4634,7 +4634,9 @@ bool Parser::ParseCXX11AttributeArgs(
 return true;
   }
 
-  if (ScopeName && ScopeName->isStr("omp")) {
+  // [[omp::directive]] and [[omp::sequence]] need special handling.
+  if (ScopeName && ScopeName->isStr("omp") &&
+  (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {
 Diag(AttrNameLoc, getLangOpts().OpenMP >= 51
   ? diag::warn_omp51_compat_attributes
   : diag::ext_omp_attributes);

diff  --git a/clang/test/OpenMP/attr-assume.cpp 
b/clang/test/OpenMP/attr-assume.cpp
new file mode 100644
index 00..09c22f98d1e299
--- /dev/null
+++ b/clang/test/OpenMP/attr-assume.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+[[omp::assume(3)]] void f1(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume(int)]] void f2(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume(for)]] void f3(); // expected-error {{expected string literal as 
argument of 'assume' attribute}}
+[[omp::assume("")]] void f4(); // expected-warning {{unknown assumption 
string ''; attribute is potentially ignored}}
+[[omp::assume("omp_no_openmp")]] void f5();
+[[omp::assume("omp_noopenmp")]] void f6(); // expected-warning {{unknown 
assumption string 'omp_noopenmp' may be misspelled; attribute is potentially 
ignored, did you mean 'omp_no_openmp'?}}
+[[omp::assume("omp_no_openmp_routine")]] void f7(); // expected-warning 
{{unknown assumption string 'omp_no_openmp_routine' may be misspelled; 
attribute is potentially ignored, did you mean 'omp_no_openmp_routines'?}}
+[[omp::assume("omp_no_openmp1")]] void f8(); // expected-warning {{unknown 
assumption string 'omp_no_openmp1' may be misspelled; attribute is potentially 
ignored, did you mean 'omp_no_openmp'?}}
+[[omp::assume("omp_no_openmp", "omp_no_openmp")]] void f9(); // expected-error 
{{'assume' attribute takes one argument}}
+
+[[omp::assume(3)]] int g1; // expected-error {{expected st

[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

2024-03-12 Thread via cfe-commits

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


[clang] [Clang] [Parser] Support [[omp::assume]] (PR #84582)

2024-03-12 Thread via cfe-commits

Sirraide wrote:

As I mentioned, I’m going to make a follow-up pr to this soon so we can discuss 
what to do with `__attribute__((assume))`/`[[clang::assume]]`.

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


[clang] [clang][Sema] Track trivial-relocatability as a type trait (PR #84621)

2024-03-12 Thread Amirreza Ashouri via cfe-commits

https://github.com/AMP999 updated 
https://github.com/llvm/llvm-project/pull/84621

>From 6e127e5794efafaabf82b6c3d5e0634ddcfee977 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Sat, 2 Mar 2024 15:37:33 +0330
Subject: [PATCH 1/3] [clang][Sema] Track trivial-relocatability as a type
 trait

To resolve llvm#69394, this patch separates trivial-relocatability's logic from 
`canPassInRegisters` to decide if a type is trivial-relocatable. A type passed 
in registers doesn't necessarily mean trivial-relocatability of that type(e.g. 
on Windows) i.e. it gives us an unintended false positive. This change would be 
beneficial for Abseil since they rely upon these semantics.
By these changes now:
User-provided special members prevent natural trivial-relocatabilitiy.
It's important because Abseil and maybe others assume the assignment 
operator doesn't have an impact on the trivial-relocatability of a type.
In fact, it does have an effect, and with a user-provided assignment 
operator, the compiler should only accept it as trivial-relocatable if it's 
implied by the `[[clang::trivial_abi]]` attribute.
Just because a type can pass in registers doesn't necessarily mean it's 
trivial-relocatable.
The `[[clang::trivial_abi]]` attribute always implies trivial-relocatability, 
even if it can't pass in registers.
The trait has extensive tests for both old and new behaviors. Test aggregation 
of
both kinds of types as data members; inheritance; virtual member functions
and virtual bases; const and reference data members; and reference types.

Fixes llvm#69394
---
 .../clang/AST/CXXRecordDeclDefinitionBits.def |   5 +
 clang/include/clang/AST/DeclCXX.h |   3 +
 clang/lib/AST/DeclCXX.cpp |  45 +++-
 clang/lib/AST/Type.cpp|   4 +-
 clang/test/SemaCXX/attr-trivial-abi.cpp   |  35 --
 .../test/SemaCXX/is-trivially-relocatable.cpp | 106 ++
 clang/test/SemaCXX/type-traits.cpp|  56 +
 7 files changed, 214 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaCXX/is-trivially-relocatable.cpp

diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def 
b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index cdf0804680ad0a..36d3cfb7dfe85b 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -189,6 +189,11 @@ FIELD(DeclaredNonTrivialSpecialMembers, 6, MERGE_OR)
 /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
 FIELD(DeclaredNonTrivialSpecialMembersForCall, 6, MERGE_OR)
 
+/// True when this class's bases and fields are all trivially relocatable
+/// or references, and the class itself has no user-provided special
+/// member functions.
+FIELD(IsNaturallyTriviallyRelocatable, 1, NO_MERGE)
+
 /// True when this class has a destructor with no semantic effect.
 FIELD(HasIrrelevantDestructor, 1, NO_MERGE)
 
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..a58126c98597b0 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1386,6 +1386,9 @@ class CXXRecordDecl : public RecordDecl {
 (SMF_CopyConstructor | SMF_MoveConstructor | SMF_Destructor);
   }
 
+  /// Determine whether this class is trivially relocatable
+  bool isTriviallyRelocatable() const;
+
   /// Determine whether declaring a const variable with this type is ok
   /// per core issue 253.
   bool allowConstDefaultInit() const {
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 1c3dcf63465c68..5cd1e6d8d720ef 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -95,7 +95,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl 
*D)
   DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
   HasTrivialSpecialMembersForCall(SMF_All),
   DeclaredNonTrivialSpecialMembers(0),
-  DeclaredNonTrivialSpecialMembersForCall(0), 
HasIrrelevantDestructor(true),
+  DeclaredNonTrivialSpecialMembersForCall(0),
+  IsNaturallyTriviallyRelocatable(true), HasIrrelevantDestructor(true),
   HasConstexprNonCopyMoveConstructor(false),
   HasDefaultedDefaultConstructor(false),
   DefaultedDefaultConstructorIsConstexpr(true),
@@ -279,6 +280,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
 
   //   An aggregate is a class with [...] no virtual functions.
   data().Aggregate = false;
+
+  // A trivially relocatable class is a class:
+  // -- which has no virtual member functions or virtual base classes
+  data().IsNaturallyTriviallyRelocatable = false;
 }
 
 // C++0x [class]p7:
@@ -293,6 +298,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
 if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
   data().HasNonLiteralTypeFieldsOrBases = true;
 
+if (Base->isVirtual()

[clang] 80ab823 - [analyzer] Accept C library functions from the `std` namespace (#84469)

2024-03-12 Thread via cfe-commits

Author: NagyDonat
Date: 2024-03-12T13:51:12+01:00
New Revision: 80ab8234ac309418637488b97e0a62d8377b2ecf

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

LOG: [analyzer] Accept C library functions from the `std` namespace (#84469)

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`.

-

Co-authored-by: Balazs Benics 

Added: 
clang/unittests/StaticAnalyzer/IsCLibraryFunctionTest.cpp

Modified: 
clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
clang/unittests/StaticAnalyzer/CMakeLists.txt
llvm/utils/gn/secondary/clang/unittests/StaticAnalyzer/BUILD.gn

Removed: 




diff  --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
index 3432d2648633c2..b4e1636130ca7c 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 namespace `std`.)
 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..1a9bff529e9bb1 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -87,9 +87,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 ).
+  const DeclContext *DC = FD->getDeclContext()->getRedeclContext();
+  if (!(DC->isTranslationUnit() || DC->isStdNamespace()))
 return false;
 
   // If this function is not externally visible, it is not a C library 
function.

diff  --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt 
b/clang/unittests/StaticAnalyzer/CMakeLists.txt
index 775f0f8486b8f9..db56e77331b821 100644
--- a/clang/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_unittest(StaticAnalysisTests
   CallEventTest.cpp
   ConflictingEvalCallsTest.cpp
   FalsePositiveRefutationBRVisitorTest.cpp
+  IsCLibraryFunctionTest.cpp
   NoStateChangeFuncVisitorTest.cpp
   ParamRegionTest.cpp
   RangeSetTest.cpp

diff  --git a/clang/unittests/StaticAnalyzer/IsCLibraryFunctionTest.cpp 
b/clang/unittests/StaticAnalyzer/IsCLibraryFunctionTest.cpp
new file mode 100644
index 00..19c66cc6bee1eb
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/IsCLibraryFunctionTest.cpp
@@ -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 con

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

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


https://github.com/NagyDonat closed 
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] 0b2c24e - Fix warning message when using negative complex range options. (#84567)

2024-03-12 Thread via cfe-commits

Author: Zahira Ammarguellat
Date: 2024-03-12T08:51:38-04:00
New Revision: 0b2c24e0b33236c1dec39fe8b007b4c6aeb170b3

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

LOG: Fix warning message when using negative complex range options. (#84567)

When `-fcx-no-limited-range` or` -fno-cx-fortran-rules` follows another
complex range option on the command line, it will trigger a warning with
empty message.
`warning: overriding '-fcx-fortran-rules' option with ''
[-Woverriding-option]`
or
`warning: overriding '-fcx-limited-range' option with ''
[-Woverriding-option]`
This patch fixes that.

Added: 


Modified: 
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/Driver/range.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index cc568b9a715bbe..6246a28a13060e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2687,8 +2687,8 @@ static void CollectArgsForIntegratedAssembler(Compilation 
&C,
   }
 }
 
-static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range) {
-  StringRef RangeStr = "";
+static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range,
+   StringRef Option) {
   switch (Range) {
   case LangOptions::ComplexRangeKind::CX_Limited:
 return "-fcx-limited-range";
@@ -2697,17 +2697,32 @@ static StringRef 
EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range) {
 return "-fcx-fortran-rules";
 break;
   default:
-return RangeStr;
+return Option;
 break;
   }
 }
 
 static void EmitComplexRangeDiag(const Driver &D,
  LangOptions::ComplexRangeKind Range1,
- LangOptions::ComplexRangeKind Range2) {
-  if (Range1 != Range2 && Range1 != LangOptions::ComplexRangeKind::CX_None)
-D.Diag(clang::diag::warn_drv_overriding_option)
-<< EnumComplexRangeToStr(Range1) << EnumComplexRangeToStr(Range2);
+ LangOptions::ComplexRangeKind Range2,
+ StringRef Option = StringRef()) {
+  if (Range1 != Range2 && Range1 != LangOptions::ComplexRangeKind::CX_None) {
+bool NegateFortranOption = false;
+bool NegateLimitedOption = false;
+if (!Option.empty()) {
+  NegateFortranOption =
+  Range1 == LangOptions::ComplexRangeKind::CX_Fortran &&
+  Option == "-fno-cx-fortran-rules";
+  NegateLimitedOption =
+  Range1 == LangOptions::ComplexRangeKind::CX_Limited &&
+  Option == "-fno-cx-limited-range";
+}
+if (Option.empty() ||
+!Option.empty() && !NegateFortranOption && !NegateLimitedOption)
+  D.Diag(clang::diag::warn_drv_overriding_option)
+  << EnumComplexRangeToStr(Range1, Option)
+  << EnumComplexRangeToStr(Range2, Option);
+  }
 }
 
 static std::string
@@ -2815,7 +2830,8 @@ static void RenderFloatingPointOptions(const ToolChain 
&TC, const Driver &D,
   break;
 }
 case options::OPT_fno_cx_limited_range:
-  EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
+  EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full,
+   "-fno-cx-limited-range");
   Range = LangOptions::ComplexRangeKind::CX_Full;
   break;
 case options::OPT_fcx_fortran_rules: {
@@ -2824,7 +2840,8 @@ static void RenderFloatingPointOptions(const ToolChain 
&TC, const Driver &D,
   break;
 }
 case options::OPT_fno_cx_fortran_rules:
-  EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
+  EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full,
+   "-fno-cx-fortran-rules");
   Range = LangOptions::ComplexRangeKind::CX_Full;
   break;
 case options::OPT_ffp_model_EQ: {

diff  --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c
index 49116df2f4480e..2d1fd7f9f1a9d5 100644
--- a/clang/test/Driver/range.c
+++ b/clang/test/Driver/range.c
@@ -12,12 +12,23 @@
 // RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=FRTRN %s
 
+// RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \
+// RUN:   -fno-cx-fortran-rules | FileCheck --check-prefix=FULL %s
+
+// RUN: %clang -### -target x86_64 -fcx-fortran-rules -fno-cx-limited-range \
+// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN3 %s
+
 // RUN: %clang -### -target x86_64 -fno-cx-fortran-rules -c %s 2>&1 \
 // RUN:   | FileCheck  %s
 
-// RUN: %clang -### -target x86_64 -fcx-limited-range \
-// RUN: -fcx-fortran-rules -c %s 2>&1 \
-// RUN:   | FileCheck --check-prefix=WARN1 %s
+// RUN: %clang -### -target x86_64 -fcx-limited-range -fcx-f

[clang] Fix warning message when using negative complex range options. (PR #84567)

2024-03-12 Thread Zahira Ammarguellat via cfe-commits

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


[clang] c7f1a98 - [OpenCL] Elaborate about BIenqueue_kernel expansion; NFC

2024-03-12 Thread Sven van Haastregt via cfe-commits

Author: Sven van Haastregt
Date: 2024-03-12T12:53:22Z
New Revision: c7f1a987a66a1ba0865ecc18adbe4dc8dbc0c788

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

LOG: [OpenCL] Elaborate about BIenqueue_kernel expansion; NFC

Added: 


Modified: 
clang/lib/CodeGen/CGBuiltin.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 20c35757939152..93ab465079777b 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5460,7 +5460,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   }
 
   // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
-  // It contains four 
diff erent overload formats specified in Table 6.13.17.1.
+  // Table 6.13.17.1 specifies four overload forms of enqueue_kernel.
+  // The code below expands the builtin call to a call to one of the following
+  // functions that an OpenCL runtime library will have to provide:
+  //   __enqueue_kernel_basic
+  //   __enqueue_kernel_varargs
+  //   __enqueue_kernel_basic_events
+  //   __enqueue_kernel_events_varargs
   case Builtin::BIenqueue_kernel: {
 StringRef Name; // Generated function call name
 unsigned NumArgs = E->getNumArgs();



___
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-12 Thread Stefan Gränitz via cfe-commits

https://github.com/weliveindetail closed 
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] bde7a6b - [clang-repl] Expose CreateExecutor() and ResetExecutor() in extended Interpreter interface (#84460)

2024-03-12 Thread via cfe-commits

Author: Stefan Gränitz
Date: 2024-03-12T13:55:38+01:00
New Revision: bde7a6b791872b63456cb4e50e63046728a65196

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

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

IncrementalExecutor is an implementation detail of the Interpreter. In
order to test extended features properly, we must be able to setup and
tear down the executor manually.

Added: 


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

Removed: 




diff  --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 469ce1fd75bf84..1dcba1ef967980 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -96,7 +96,6 @@ class Interpreter {
   // An optional parser for CUDA offloading
   std::unique_ptr DeviceParser;
 
-  llvm::Error CreateExecutor();
   unsigned InitPTUSize = 0;
 
   // This member holds the last result of the value printing. It's a class
@@ -114,6 +113,14 @@ class Interpreter {
   // That's useful for testing and out-of-tree clients.
   Interpreter(std::unique_ptr CI, llvm::Error &Err);
 
+  // Create the internal IncrementalExecutor, or re-create it after calling
+  // ResetExecutor().
+  llvm::Error CreateExecutor();
+
+  // Delete the internal IncrementalExecutor. This causes a hard shutdown of 
the
+  // JIT engine. In particular, it doesn't run cleanup or destructors.
+  void ResetExecutor();
+
   // 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

diff  --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index e293fefb524963..7fa52f2f15fc49 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -375,6 +375,10 @@ Interpreter::Parse(llvm::StringRef Code) {
 llvm::Error Interpreter::CreateExecutor() {
   const clang::TargetInfo &TI =
   getCompilerInstance()->getASTContext().getTargetInfo();
+  if (IncrExecutor)
+return llvm::make_error("Operation failed. "
+   "Execution engine exists",
+   std::error_code());
   llvm::Error Err = llvm::Error::success();
   auto Executor = std::make_unique(*TSCtx, Err, TI);
   if (!Err)
@@ -383,6 +387,8 @@ llvm::Error Interpreter::CreateExecutor() {
   return Err;
 }
 
+void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
+
 llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
   assert(T.TheModule);
   if (!IncrExecutor) {

diff  --git a/clang/unittests/Interpreter/CMakeLists.txt 
b/clang/unittests/Interpreter/CMakeLists.txt
index 046d96ad0ec644..498070b43d922e 100644
--- a/clang/unittests/Interpreter/CMakeLists.txt
+++ b/clang/unittests/Interpreter/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
   OrcJIT
   Support
   TargetParser
+  TestingSupport
   )
 
 add_clang_unittest(ClangReplInterpreterTests

diff  --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp 
b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
index 4e9f2dba210a37..f1c3d65ab0a95d 100644
--- a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
@@ -27,6 +27,30 @@
 using namespace clang;
 namespace {
 
+class TestCreateResetExecutor : public Interpreter {
+public:
+  TestCreateResetExecutor(std::unique_ptr CI,
+  llvm::Error &Err)
+  : Interpreter(std::move(CI), Err) {}
+
+  llvm::Error testCreateExecutor() { return Interpreter::CreateExecutor(); }
+
+  void resetExecutor() { Interpreter::ResetExecutor(); }
+};
+
+TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
+  clang::IncrementalCompilerBuilder CB;
+  llvm::Error ErrOut = llvm::Error::success();
+  TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut);
+  cantFail(std::move(ErrOut));
+  cantFail(Interp.testCreateExecutor());
+  Interp.resetExecutor();
+  cantFail(Interp.testCreateExecutor());
+  EXPECT_THAT_ERROR(Interp.testCreateExecutor(),
+llvm::FailedWithMessage("Operation failed. "
+"Execution engine exists"));
+}
+
 class RecordRuntimeIBMetrics : public Interpreter {
   struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
 NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {}


  

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits

https://github.com/Discookie commented:

Thanks for the reviews! Fixed a lot of the comments, and I have a few more 
things to test for the rest.

@gribozavr Thank you for the thorough introduction to your approaches, and the 
links to related works as well! Templated types are something I didn't take a 
look at before, will need to experiment with those as well.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,171 @@
+//===--- NullCheckAfterDereferenceCheck.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 "NullCheckAfterDereferenceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang::tidy::bugprone {
+
+using ast_matchers::MatchFinder;
+using dataflow::NullCheckAfterDereferenceDiagnoser;
+using dataflow::NullPointerAnalysisModel;
+
+static constexpr llvm::StringLiteral FuncID("fun");
+
+struct ExpandedResult {
+  SourceLocation WarningLoc;
+  std::optional DerefLoc;
+};
+
+using ExpandedResultType =
+std::pair, std::vector>;
+
+static std::optional
+analyzeFunction(const FunctionDecl &FuncDecl) {
+  using dataflow::ControlFlowContext;
+  using dataflow::DataflowAnalysisState;
+  using llvm::Expected;
+
+  ASTContext &ASTCtx = FuncDecl.getASTContext();
+
+  if (FuncDecl.getBody() == nullptr) {
+return std::nullopt;
+  }
+
+  Expected Context =
+  ControlFlowContext::build(FuncDecl, *FuncDecl.getBody(), ASTCtx);
+  if (!Context)
+return std::nullopt;
+
+  dataflow::DataflowAnalysisContext AnalysisContext(
+  std::make_unique());
+  dataflow::Environment Env(AnalysisContext, FuncDecl);
+  NullPointerAnalysisModel Analysis(ASTCtx);
+  NullCheckAfterDereferenceDiagnoser Diagnoser;
+  NullCheckAfterDereferenceDiagnoser::ResultType Diagnostics;
+
+  using LatticeState = 
DataflowAnalysisState;

Discookie wrote:

`State` works, yep.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,625 @@
+//===-- NullPointerAnalysisModel.cpp *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+namespace {
+using namespace ast_matchers;
+
+constexpr char kCond[] = "condition";
+constexpr char kVar[] = "var";
+constexpr char kValue[] = "value";
+constexpr char kIsNonnull[] = "is-nonnull";
+constexpr char kIsNull[] = "is-null";
+
+enum class SatisfiabilityResult {
+  // Returned when the value was not initialized yet.
+  Nullptr,
+  // Special value that signals that the boolean value can be anything.
+  // It signals that the underlying formulas are too complex to be calculated
+  // efficiently.
+  Top,
+  // Equivalent to the literal True in the current environment.
+  True,
+  // Equivalent to the literal False in the current environment.
+  False,
+  // Both True and False values could be produced with an appropriate set of
+  // conditions.
+  Unknown
+};
+
+using SR = SatisfiabilityResult;
+
+// FIXME: These AST matchers should also be exported via the
+// NullPointerAnalysisModel class, for tests
+auto ptrToVar(llvm::StringRef VarName = kVar) {
+  return traverse(TK_IgnoreUnlessSpelledInSource,
+  declRefExpr(hasType(isAnyPointer())).bind(VarName));
+}
+
+auto derefMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ptrToVar(;
+}
+
+auto arrowMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  memberExpr(allOf(isArrow(), hasObjectExpression(ptrToVar();
+}
+
+auto castExprMatcher() {
+  return castExpr(hasCastKind(CK_PointerToBoolean),
+  hasSourceExpression(ptrToVar()))

Discookie wrote:

It indeed shouldn't, I was afraid that a more complex argument would run into 
issues with being rvalue vs lvalue, and the differences between the two had me 
crash the framework a couple times before. Seems to have no issues anymore, so 
changed and renamed `ptrToVar()` to take any pointer value.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,162 @@
+.. title:: clang-tidy - bugprone-null-check-after-dereference
+
+bugprone-null-check-after-dereference
+=
+
+.. note::
+
+   This check uses a flow-sensitive static analysis to produce its
+   results. Therefore, it may be more resource intensive (RAM, CPU) than the
+   average clang-tidy check.
+
+This check identifies redundant pointer null-checks, by finding cases where the
+pointer cannot be null at the location of the null-check.
+
+Redundant null-checks can signal faulty assumptions about the current value of
+a pointer at different points in the program. Either the null-check is
+redundant, or there could be a null-pointer dereference earlier in the program.
+
+.. code-block:: c++
+
+   int f(int *ptr) {
+ *ptr = 20; // note: one of the locations where the pointer's value cannot 
be null
+ // ...
+ if (ptr) { // bugprone: pointer is checked even though it cannot be null 
at this point
+   return *ptr;
+ }
+ return 0;
+   }
+
+Supported pointer operations
+
+
+Pointer null-checks
+---
+
+The checker currently supports null-checks on pointers that use
+``operator bool``, such as when being used as the condition
+for an `if` statement.

Discookie wrote:

I thought I implemented it, but apparently not, good catch!

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,171 @@
+//===--- NullCheckAfterDereferenceCheck.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 "NullCheckAfterDereferenceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang::tidy::bugprone {
+
+using ast_matchers::MatchFinder;
+using dataflow::NullCheckAfterDereferenceDiagnoser;
+using dataflow::NullPointerAnalysisModel;
+
+static constexpr llvm::StringLiteral FuncID("fun");
+
+struct ExpandedResult {
+  SourceLocation WarningLoc;
+  std::optional DerefLoc;
+};
+
+using ExpandedResultType =
+std::pair, std::vector>;
+
+static std::optional
+analyzeFunction(const FunctionDecl &FuncDecl) {
+  using dataflow::ControlFlowContext;
+  using dataflow::DataflowAnalysisState;
+  using llvm::Expected;
+
+  ASTContext &ASTCtx = FuncDecl.getASTContext();
+
+  if (FuncDecl.getBody() == nullptr) {
+return std::nullopt;
+  }
+
+  Expected Context =
+  ControlFlowContext::build(FuncDecl, *FuncDecl.getBody(), ASTCtx);
+  if (!Context)
+return std::nullopt;
+
+  dataflow::DataflowAnalysisContext AnalysisContext(
+  std::make_unique());
+  dataflow::Environment Env(AnalysisContext, FuncDecl);
+  NullPointerAnalysisModel Analysis(ASTCtx);
+  NullCheckAfterDereferenceDiagnoser Diagnoser;
+  NullCheckAfterDereferenceDiagnoser::ResultType Diagnostics;
+
+  using LatticeState = 
DataflowAnalysisState;
+  using DetailMaybeLatticeStates = std::vector>;
+
+  auto DiagnoserImpl = [&ASTCtx, &Diagnoser,
+&Diagnostics](const CFGElement &Elt,
+  const LatticeState &S) mutable -> void {
+auto EltDiagnostics = Diagnoser.diagnose(ASTCtx, &Elt, S.Env);
+llvm::move(EltDiagnostics.first, std::back_inserter(Diagnostics.first));
+llvm::move(EltDiagnostics.second, std::back_inserter(Diagnostics.second));
+  };
+
+  Expected BlockToOutputState =
+  dataflow::runDataflowAnalysis(*Context, Analysis, Env, DiagnoserImpl);
+
+  if (llvm::Error E = BlockToOutputState.takeError()) {
+llvm::dbgs() << "Dataflow analysis failed: " << 
llvm::toString(std::move(E))
+ << ".\n";
+return std::nullopt;
+  }
+
+  ExpandedResultType ExpandedDiagnostics;
+
+  llvm::transform(Diagnostics.first,
+  std::back_inserter(ExpandedDiagnostics.first),
+  [&](SourceLocation WarningLoc) -> ExpandedResult {
+if (auto Val = Diagnoser.WarningLocToVal[WarningLoc];
+auto DerefExpr = Diagnoser.ValToDerefLoc[Val]) {
+  return {WarningLoc, DerefExpr->getBeginLoc()};
+}
+
+return {WarningLoc, std::nullopt};
+  });
+
+  llvm::transform(Diagnostics.second,
+  std::back_inserter(ExpandedDiagnostics.second),
+  [&](SourceLocation WarningLoc) -> ExpandedResult {
+if (auto Val = Diagnoser.WarningLocToVal[WarningLoc];
+auto DerefExpr = Diagnoser.ValToDerefLoc[Val]) {
+  return {WarningLoc, DerefExpr->getBeginLoc()};
+}
+
+return {WarningLoc, std::nullopt};
+  });
+
+  return ExpandedDiagnostics;
+}
+
+void NullCheckAfterDereferenceCheck::registerMatchers(MatchFinder *Finder) {
+  using namespace ast_matchers;
+
+  auto hasPointerValue =
+  hasDescendant(NullPointerAnalysisModel::ptrValueMatcher());

Discookie wrote:

It's in the model header file, 
[here](https://github.com/llvm/llvm-project/pull/84166/files#diff-bbce48612d4066ae8a050f787028e52d9f7d957a2f8b834a06f69dfefb155b6eR59),
 implemented 
[here](https://github.com/llvm/llvm-project/pull/84166/files#diff-2c9f636b2ee4dd92e7a2119fcddcc68ddaefe218a1a39f0d1492ac4f94d05f87R417).
 In hindsight, it seems like some meaningless code deduplication that isn't 
really worth exporting to a separate function though.


https://github.com/llvm/llvm-project

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,625 @@
+//===-- NullPointerAnalysisModel.cpp *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+namespace {
+using namespace ast_matchers;
+
+constexpr char kCond[] = "condition";
+constexpr char kVar[] = "var";
+constexpr char kValue[] = "value";
+constexpr char kIsNonnull[] = "is-nonnull";
+constexpr char kIsNull[] = "is-null";
+
+enum class SatisfiabilityResult {
+  // Returned when the value was not initialized yet.
+  Nullptr,
+  // Special value that signals that the boolean value can be anything.
+  // It signals that the underlying formulas are too complex to be calculated
+  // efficiently.
+  Top,
+  // Equivalent to the literal True in the current environment.
+  True,
+  // Equivalent to the literal False in the current environment.
+  False,
+  // Both True and False values could be produced with an appropriate set of
+  // conditions.
+  Unknown
+};
+
+using SR = SatisfiabilityResult;
+
+// FIXME: These AST matchers should also be exported via the
+// NullPointerAnalysisModel class, for tests
+auto ptrToVar(llvm::StringRef VarName = kVar) {
+  return traverse(TK_IgnoreUnlessSpelledInSource,

Discookie wrote:

The traversal here was only necessary because I was binding the name to the 
underlying variable directly.
Now that arbitrary pointer values are supported, it's not needed, the framework 
is indeed good at passing values through other implicit casts.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,330 @@
+// RUN: %check_clang_tidy %s bugprone-null-check-after-dereference %t
+
+struct S {
+  int a;
+};
+
+int warning_deref(int *p) {
+  *p = 42;
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point [bugprone-null-check-after-dereference]
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+  // FIXME: If there's a direct path, make the error message more precise, ie. 
remove `one of the locations`
+*p += 20;
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int warning_member(S *q) {
+  q->a = 42;
+
+  if (q) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+q->a += 20;
+return q->a;
+  } else {
+return 0;
+  }
+}
+
+int negative_warning(int *p) {
+  *p = 42;
+
+  if (!p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int no_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  }
+
+  if (p) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point 

Discookie wrote:

They are, I just wanted to show that this is the place where a false-positive 
would come up. Would a ``// no-warning`` or similar be better, or is removing 
the line just fine?

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,330 @@
+// RUN: %check_clang_tidy %s bugprone-null-check-after-dereference %t
+
+struct S {
+  int a;
+};
+
+int warning_deref(int *p) {
+  *p = 42;
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point [bugprone-null-check-after-dereference]
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+  // FIXME: If there's a direct path, make the error message more precise, ie. 
remove `one of the locations`
+*p += 20;
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int warning_member(S *q) {
+  q->a = 42;
+
+  if (q) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+q->a += 20;
+return q->a;
+  } else {
+return 0;
+  }
+}
+
+int negative_warning(int *p) {
+  *p = 42;
+
+  if (!p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int no_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  }
+
+  if (p) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point 
+*p += 20;
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int else_branch_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  } else {
+*p = 20;
+  }
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-7]]:5: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int two_branches_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  }
+  
+  if (!b) {
+*p = 20;
+  }
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-9]]:5: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int two_branches_reversed(int *p, bool b) {

Discookie wrote:

Indeed - it was testing the check's behavior from back when variables' `Value`s 
weren't initialized by default.
Merging a variable that only had a `Value` on one of the branches caused weird 
behavior - same reason the leftover ``initializeFunctionParameters()`` was 
still in the code.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,171 @@
+//===--- NullCheckAfterDereferenceCheck.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 "NullCheckAfterDereferenceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang::tidy::bugprone {
+
+using ast_matchers::MatchFinder;
+using dataflow::NullCheckAfterDereferenceDiagnoser;
+using dataflow::NullPointerAnalysisModel;
+
+static constexpr llvm::StringLiteral FuncID("fun");
+
+struct ExpandedResult {
+  SourceLocation WarningLoc;
+  std::optional DerefLoc;
+};
+
+using ExpandedResultType =
+std::pair, std::vector>;
+
+static std::optional
+analyzeFunction(const FunctionDecl &FuncDecl) {
+  using dataflow::ControlFlowContext;
+  using dataflow::DataflowAnalysisState;
+  using llvm::Expected;
+
+  ASTContext &ASTCtx = FuncDecl.getASTContext();
+
+  if (FuncDecl.getBody() == nullptr) {
+return std::nullopt;
+  }
+
+  Expected Context =
+  ControlFlowContext::build(FuncDecl, *FuncDecl.getBody(), ASTCtx);
+  if (!Context)
+return std::nullopt;
+
+  dataflow::DataflowAnalysisContext AnalysisContext(
+  std::make_unique());
+  dataflow::Environment Env(AnalysisContext, FuncDecl);
+  NullPointerAnalysisModel Analysis(ASTCtx);
+  NullCheckAfterDereferenceDiagnoser Diagnoser;
+  NullCheckAfterDereferenceDiagnoser::ResultType Diagnostics;
+
+  using LatticeState = 
DataflowAnalysisState;
+  using DetailMaybeLatticeStates = std::vector>;
+
+  auto DiagnoserImpl = [&ASTCtx, &Diagnoser,
+&Diagnostics](const CFGElement &Elt,
+  const LatticeState &S) mutable -> void {
+auto EltDiagnostics = Diagnoser.diagnose(ASTCtx, &Elt, S.Env);
+llvm::move(EltDiagnostics.first, std::back_inserter(Diagnostics.first));
+llvm::move(EltDiagnostics.second, std::back_inserter(Diagnostics.second));
+  };
+
+  Expected BlockToOutputState =
+  dataflow::runDataflowAnalysis(*Context, Analysis, Env, DiagnoserImpl);
+
+  if (llvm::Error E = BlockToOutputState.takeError()) {
+llvm::dbgs() << "Dataflow analysis failed: " << 
llvm::toString(std::move(E))
+ << ".\n";
+return std::nullopt;
+  }
+
+  ExpandedResultType ExpandedDiagnostics;
+
+  llvm::transform(Diagnostics.first,
+  std::back_inserter(ExpandedDiagnostics.first),
+  [&](SourceLocation WarningLoc) -> ExpandedResult {
+if (auto Val = Diagnoser.WarningLocToVal[WarningLoc];
+auto DerefExpr = Diagnoser.ValToDerefLoc[Val]) {
+  return {WarningLoc, DerefExpr->getBeginLoc()};
+}
+
+return {WarningLoc, std::nullopt};
+  });
+
+  llvm::transform(Diagnostics.second,
+  std::back_inserter(ExpandedDiagnostics.second),
+  [&](SourceLocation WarningLoc) -> ExpandedResult {
+if (auto Val = Diagnoser.WarningLocToVal[WarningLoc];
+auto DerefExpr = Diagnoser.ValToDerefLoc[Val]) {
+  return {WarningLoc, DerefExpr->getBeginLoc()};
+}
+
+return {WarningLoc, std::nullopt};
+  });
+
+  return ExpandedDiagnostics;
+}
+
+void NullCheckAfterDereferenceCheck::registerMatchers(MatchFinder *Finder) {
+  using namespace ast_matchers;
+
+  auto hasPointerValue =
+  hasDescendant(NullPointerAnalysisModel::ptrValueMatcher());
+  Finder->addMatcher(
+  decl(anyOf(functionDecl(unless(isExpansionInSystemHeader()),
+  // FIXME: Remove the filter below when lambdas 
are
+  // well supported by the check.
+  
unless(hasDeclContext(cxxRecordDecl(isLambda(,
+  hasBody(hasPointerValue)),
+ cxxConstructorDecl(hasAnyConstructorInitializer(
+ withInitializer(hasPointerValue)
+  .bind(Fu

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,330 @@
+// RUN: %check_clang_tidy %s bugprone-null-check-after-dereference %t
+
+struct S {
+  int a;
+};
+
+int warning_deref(int *p) {
+  *p = 42;
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point [bugprone-null-check-after-dereference]
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+  // FIXME: If there's a direct path, make the error message more precise, ie. 
remove `one of the locations`
+*p += 20;
+return *p;

Discookie wrote:

Removed a couple of the redundant lines, but I do wanna go over the tests once 
again, and rewrite them to be more concise.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,625 @@
+//===-- NullPointerAnalysisModel.cpp *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+namespace {
+using namespace ast_matchers;
+
+constexpr char kCond[] = "condition";
+constexpr char kVar[] = "var";
+constexpr char kValue[] = "value";
+constexpr char kIsNonnull[] = "is-nonnull";
+constexpr char kIsNull[] = "is-null";
+
+enum class SatisfiabilityResult {
+  // Returned when the value was not initialized yet.
+  Nullptr,
+  // Special value that signals that the boolean value can be anything.
+  // It signals that the underlying formulas are too complex to be calculated
+  // efficiently.
+  Top,
+  // Equivalent to the literal True in the current environment.
+  True,
+  // Equivalent to the literal False in the current environment.
+  False,
+  // Both True and False values could be produced with an appropriate set of
+  // conditions.
+  Unknown
+};
+
+using SR = SatisfiabilityResult;
+
+// FIXME: These AST matchers should also be exported via the
+// NullPointerAnalysisModel class, for tests
+auto ptrToVar(llvm::StringRef VarName = kVar) {
+  return traverse(TK_IgnoreUnlessSpelledInSource,
+  declRefExpr(hasType(isAnyPointer())).bind(VarName));
+}
+
+auto derefMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ptrToVar(;
+}
+
+auto arrowMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  memberExpr(allOf(isArrow(), hasObjectExpression(ptrToVar();
+}
+
+auto castExprMatcher() {
+  return castExpr(hasCastKind(CK_PointerToBoolean),
+  hasSourceExpression(ptrToVar()))
+  .bind(kCond);
+}
+
+auto nullptrMatcher() {
+  return castExpr(hasCastKind(CK_NullToPointer)).bind(kVar);
+}
+
+auto addressofMatcher() {
+  return unaryOperator(hasOperatorName("&")).bind(kVar);
+}
+
+auto functionCallMatcher() {
+  return callExpr(hasDeclaration(functionDecl(returns(isAnyPointer()
+  .bind(kVar);
+}
+
+auto assignMatcher() {
+  return binaryOperation(isAssignmentOperator(), hasLHS(ptrToVar()),
+ hasRHS(expr().bind(kValue)));
+}
+
+auto anyPointerMatcher() { return expr(hasType(isAnyPointer())).bind(kVar); }
+
+// Only computes simple comparisons against the literals True and False in the
+// environment. Faster, but produces many Unknown values.
+SatisfiabilityResult shallowComputeSatisfiability(BoolValue *Val,
+  const Environment &Env) {
+  if (!Val)
+return SR::Nullptr;
+
+  if (isa(Val))
+return SR::Top;
+
+  if (Val == &Env.getBoolLiteralValue(true))
+return SR::True;
+
+  if (Val == &Env.getBoolLiteralValue(false))
+return SR::False;
+
+  return SR::Unknown;
+}
+
+// Computes satisfiability by using the flow condition. Slower, but more
+// precise.
+SatisfiabilityResult computeSatisfiability(BoolValue *Val,
+   const Environment &Env) {
+  // Early return with the fast compute values.
+  if (SatisfiabilityResult ShallowResult =
+  shallowComputeSatisfiability(Val, Env);
+  ShallowResult != SR::Unknown) {
+return ShallowResult;
+  }
+
+  if (Env.proves(Val->formula()))
+return SR::True;
+
+  if (Env.proves(Env.arena().makeNot(Val->formula(
+return SR::False;
+
+  return SR::Unknown;
+}
+
+inline BoolValue &getVal(llvm::StringRef Name, Value &RootValue) {
+  return *cast(RootValue.getProperty(Name));
+}
+
+// Assign

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,112 @@
+//===-- NullPointerAnalysisModel.h --*- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_NULLPOINTERANALYSISMODEL_H
+#define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_NULLPOINTERANALYSISMODEL_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+class NullPointerAnalysisModel
+: public DataflowAnalysis {
+public:
+  /// A transparent wrapper around the function arguments of transferBranch().
+  /// Does not outlive the call to transferBranch().
+  struct TransferArgs {
+bool Branch;
+Environment &Env;
+  };
+
+private:
+  CFGMatchSwitch TransferMatchSwitch;
+  ASTMatchSwitch BranchTransferMatchSwitch;
+
+public:
+  explicit NullPointerAnalysisModel(ASTContext &Context);
+
+  static NoopLattice initialElement() { return {}; }
+
+  static ast_matchers::StatementMatcher ptrValueMatcher();
+
+  // Used to initialize the storage locations of function arguments.
+  // Required to merge these values within the environment.
+  void initializeFunctionParameters(const ControlFlowContext &CFCtx,
+Environment &Env);
+
+  void transfer(const CFGElement &E, NoopLattice &State, Environment &Env);
+
+  void transferBranch(bool Branch, const Stmt *E, NoopLattice &State,
+  Environment &Env);
+
+  void join(QualType Type, const Value &Val1, const Environment &Env1,
+const Value &Val2, const Environment &Env2, Value &MergedVal,
+Environment &MergedEnv) override;
+
+  ComparisonResult compare(QualType Type, const Value &Val1,
+   const Environment &Env1, const Value &Val2,
+   const Environment &Env2) override;
+
+  Value *widen(QualType Type, Value &Prev, const Environment &PrevEnv,
+   Value &Current, Environment &CurrentEnv) override;
+};
+
+class NullCheckAfterDereferenceDiagnoser {
+public:
+  struct DiagnoseArgs {
+llvm::DenseMap &ValToDerefLoc;
+llvm::DenseMap &WarningLocToVal;
+const Environment &Env;
+  };
+
+  using ResultType =
+  std::pair, std::vector>;
+
+  // Maps a pointer's Value to a dereference, null-assignment, etc.
+  // This is used later to construct the Note tag.
+  llvm::DenseMap ValToDerefLoc;
+  // Maps Maps a warning's SourceLocation to its relevant Value.
+  llvm::DenseMap WarningLocToVal;
+

Discookie wrote:

These maps are used to make the note-tags within 
`NullCheckAfterDereferenceCheck`. Their naming scheme is a bit misleading in 
that sense, and note-tags could probably also be created directly by the 
Diagnoser.

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


[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,330 @@
+// RUN: %check_clang_tidy %s bugprone-null-check-after-dereference %t
+
+struct S {
+  int a;
+};
+
+int warning_deref(int *p) {
+  *p = 42;
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point [bugprone-null-check-after-dereference]
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+  // FIXME: If there's a direct path, make the error message more precise, ie. 
remove `one of the locations`
+*p += 20;
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int warning_member(S *q) {
+  q->a = 42;
+
+  if (q) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+q->a += 20;
+return q->a;
+  } else {
+return 0;
+  }
+}
+
+int negative_warning(int *p) {
+  *p = 42;
+
+  if (!p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int no_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  }
+
+  if (p) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point 
+*p += 20;
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int else_branch_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  } else {
+*p = 20;
+  }
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-7]]:5: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int two_branches_warning(int *p, bool b) {
+  if (b) {
+*p = 42;
+  }
+  
+  if (!b) {
+*p = 20;
+  }
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-9]]:5: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+int two_branches_reversed(int *p, bool b) {
+  if (!b) {
+*p = 42;
+  }
+  
+  if (b) {
+*p = 20;
+  }
+
+  if (p) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-9]]:5: note: one of the locations where the 
pointer's value cannot be null
+return 0;
+  } else {
+*p += 20;
+return *p;
+  }
+}
+
+
+int regular_assignment(int *p, int *q) {
+  *p = 42;
+  q = p;
+
+  if (q) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-5]]:3: note: one of the locations where the 
pointer's value cannot be null
+*p += 20; 
+return *p;
+  } else {
+return 0;
+  }
+}
+
+int nullptr_assignment(int *nullptr_param, bool b) {
+  *nullptr_param = 42;
+  int *nullptr_assigned;
+
+  if (b) {
+nullptr_assigned = nullptr;
+  } else {
+nullptr_assigned = nullptr_param;
+  }
+
+  if (nullptr_assigned) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+*nullptr_assigned = 20;
+return *nullptr_assigned;
+  } else {
+return 0;
+  }
+}
+
+extern int *fncall();
+extern void refresh_ref(int *&ptr);
+extern void refresh_ptr(int **ptr);
+
+int fncall_reassignment(int *fncall_reassigned) {
+  *fncall_reassigned = 42;
+
+  fncall_reassigned = fncall();
+
+  if (fncall_reassigned) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+*fncall_reassigned = 42;
+  }
+  
+  fncall_reassigned = fncall();
+
+  *fncall_reassigned = 42;
+
+  if (fncall_reassigned) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+*fncall_reassigned = 42;
+  }
+  
+  refresh_ptr(&fncall_reassigned);
+
+  if (fncall_reassigned) {
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+*fncall_reassigned = 42;
+  }
+  
+  refresh_ptr(&fncall_reassigned);
+  *fncall_reassigned = 42;
+
+  if (fncall_reassigned) {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+// CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer'

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,625 @@
+//===-- NullPointerAnalysisModel.cpp *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+namespace {
+using namespace ast_matchers;
+
+constexpr char kCond[] = "condition";
+constexpr char kVar[] = "var";
+constexpr char kValue[] = "value";
+constexpr char kIsNonnull[] = "is-nonnull";
+constexpr char kIsNull[] = "is-null";
+
+enum class SatisfiabilityResult {
+  // Returned when the value was not initialized yet.
+  Nullptr,
+  // Special value that signals that the boolean value can be anything.
+  // It signals that the underlying formulas are too complex to be calculated
+  // efficiently.
+  Top,
+  // Equivalent to the literal True in the current environment.
+  True,
+  // Equivalent to the literal False in the current environment.
+  False,
+  // Both True and False values could be produced with an appropriate set of
+  // conditions.
+  Unknown
+};
+
+using SR = SatisfiabilityResult;
+
+// FIXME: These AST matchers should also be exported via the
+// NullPointerAnalysisModel class, for tests
+auto ptrToVar(llvm::StringRef VarName = kVar) {
+  return traverse(TK_IgnoreUnlessSpelledInSource,
+  declRefExpr(hasType(isAnyPointer())).bind(VarName));
+}
+
+auto derefMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ptrToVar(;
+}
+
+auto arrowMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  memberExpr(allOf(isArrow(), hasObjectExpression(ptrToVar();
+}
+
+auto castExprMatcher() {
+  return castExpr(hasCastKind(CK_PointerToBoolean),
+  hasSourceExpression(ptrToVar()))
+  .bind(kCond);
+}
+
+auto nullptrMatcher() {
+  return castExpr(hasCastKind(CK_NullToPointer)).bind(kVar);
+}
+
+auto addressofMatcher() {
+  return unaryOperator(hasOperatorName("&")).bind(kVar);
+}
+
+auto functionCallMatcher() {
+  return callExpr(hasDeclaration(functionDecl(returns(isAnyPointer()
+  .bind(kVar);
+}
+
+auto assignMatcher() {
+  return binaryOperation(isAssignmentOperator(), hasLHS(ptrToVar()),
+ hasRHS(expr().bind(kValue)));
+}
+
+auto anyPointerMatcher() { return expr(hasType(isAnyPointer())).bind(kVar); }
+
+// Only computes simple comparisons against the literals True and False in the
+// environment. Faster, but produces many Unknown values.
+SatisfiabilityResult shallowComputeSatisfiability(BoolValue *Val,
+  const Environment &Env) {
+  if (!Val)
+return SR::Nullptr;
+
+  if (isa(Val))
+return SR::Top;
+
+  if (Val == &Env.getBoolLiteralValue(true))
+return SR::True;
+
+  if (Val == &Env.getBoolLiteralValue(false))
+return SR::False;
+
+  return SR::Unknown;
+}
+
+// Computes satisfiability by using the flow condition. Slower, but more
+// precise.
+SatisfiabilityResult computeSatisfiability(BoolValue *Val,
+   const Environment &Env) {
+  // Early return with the fast compute values.
+  if (SatisfiabilityResult ShallowResult =
+  shallowComputeSatisfiability(Val, Env);
+  ShallowResult != SR::Unknown) {
+return ShallowResult;
+  }
+
+  if (Env.proves(Val->formula()))
+return SR::True;
+
+  if (Env.proves(Env.arena().makeNot(Val->formula(
+return SR::False;
+
+  return SR::Unknown;
+}
+
+inline BoolValue &getVal(llvm::StringRef Name, Value &RootValue) {
+  return *cast(RootValue.getProperty(Name));
+}
+
+// Assign

[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)

2024-03-12 Thread via cfe-commits


@@ -0,0 +1,625 @@
+//===-- NullPointerAnalysisModel.cpp *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines a generic null-pointer analysis model, used for finding
+// pointer null-checks after the pointer has already been dereferenced.
+//
+// Only a limited set of operations are currently recognized. Notably, pointer
+// arithmetic, null-pointer assignments and _nullable/_nonnull attributes are
+// missing as of yet.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang::dataflow {
+
+namespace {
+using namespace ast_matchers;
+
+constexpr char kCond[] = "condition";
+constexpr char kVar[] = "var";
+constexpr char kValue[] = "value";
+constexpr char kIsNonnull[] = "is-nonnull";
+constexpr char kIsNull[] = "is-null";
+
+enum class SatisfiabilityResult {
+  // Returned when the value was not initialized yet.
+  Nullptr,
+  // Special value that signals that the boolean value can be anything.
+  // It signals that the underlying formulas are too complex to be calculated
+  // efficiently.
+  Top,
+  // Equivalent to the literal True in the current environment.
+  True,
+  // Equivalent to the literal False in the current environment.
+  False,
+  // Both True and False values could be produced with an appropriate set of
+  // conditions.
+  Unknown
+};
+
+using SR = SatisfiabilityResult;
+
+// FIXME: These AST matchers should also be exported via the
+// NullPointerAnalysisModel class, for tests
+auto ptrToVar(llvm::StringRef VarName = kVar) {
+  return traverse(TK_IgnoreUnlessSpelledInSource,
+  declRefExpr(hasType(isAnyPointer())).bind(VarName));
+}
+
+auto derefMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ptrToVar(;
+}
+
+auto arrowMatcher() {
+  return traverse(
+  TK_IgnoreUnlessSpelledInSource,
+  memberExpr(allOf(isArrow(), hasObjectExpression(ptrToVar();
+}
+
+auto castExprMatcher() {
+  return castExpr(hasCastKind(CK_PointerToBoolean),
+  hasSourceExpression(ptrToVar()))
+  .bind(kCond);
+}
+
+auto nullptrMatcher() {
+  return castExpr(hasCastKind(CK_NullToPointer)).bind(kVar);
+}
+
+auto addressofMatcher() {
+  return unaryOperator(hasOperatorName("&")).bind(kVar);
+}
+
+auto functionCallMatcher() {
+  return callExpr(hasDeclaration(functionDecl(returns(isAnyPointer()
+  .bind(kVar);
+}
+
+auto assignMatcher() {
+  return binaryOperation(isAssignmentOperator(), hasLHS(ptrToVar()),
+ hasRHS(expr().bind(kValue)));
+}
+
+auto anyPointerMatcher() { return expr(hasType(isAnyPointer())).bind(kVar); }
+
+// Only computes simple comparisons against the literals True and False in the
+// environment. Faster, but produces many Unknown values.
+SatisfiabilityResult shallowComputeSatisfiability(BoolValue *Val,
+  const Environment &Env) {
+  if (!Val)
+return SR::Nullptr;
+
+  if (isa(Val))
+return SR::Top;
+
+  if (Val == &Env.getBoolLiteralValue(true))
+return SR::True;
+
+  if (Val == &Env.getBoolLiteralValue(false))
+return SR::False;
+
+  return SR::Unknown;
+}
+
+// Computes satisfiability by using the flow condition. Slower, but more
+// precise.
+SatisfiabilityResult computeSatisfiability(BoolValue *Val,

Discookie wrote:

Returning a `BoolValue &` sounds useful. I wouldn't be able to differentiate 
cases such as `nullptr` vs `unknown`, but maybe I don't even need to, since I'm 
gonna initialize the variable later anyways.

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


[clang] [llvm] Update documentation and release notes for llvm-profgen COFF support (PR #84864)

2024-03-12 Thread Tim Creech via cfe-commits


@@ -2434,6 +2449,15 @@ usual build cycle when using sample profilers for 
optimization:
it provides better call information, which improves the accuracy of
the profile data.
 
+   When using SEP:
+
+   .. code-block:: console
+
+ $ sep -start -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr 
no_filter:usr -perf-script ip,brstack -app ./code

tcreech-intel wrote:

I had omitted `-out` for the sake of brevity, but maybe this is confusing. I'll 
update it and name a specific perf.data.script file below.

https://github.com/llvm/llvm-project/pull/84864
___
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-12 Thread Erich Keane via cfe-commits

erichkeane wrote:

> > There are currently over 200 separate unions using the work-around.
> 
> Specifically, this is what Linux uses for getting C99 flexible arrays in 
> unions and alone in structs:
> 
> ```
> #define DECLARE_FLEX_ARRAY(TYPE, NAME)\
> struct { \
> struct { } __empty_ ## NAME; \
> TYPE NAME[]; \
> }
> ```
> 
> The conversion (over 6 years) from the "struct hack" to C99 flexible arrays 
> is complete, except for this wart.

That one ends up not being a problem, but presumably you are wanting to change 
that top-level 'struct' to be a 'union'?  What is the problem with making it 
`TYPE NAME[0];` ?

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-repl] Factor out CreateJITBuilder() and allow specialization in derived classes (PR #84461)

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

https://github.com/weliveindetail updated 
https://github.com/llvm/llvm-project/pull/84461

From 88271c39b30b84041b4b7fb8b8f34c211d8190d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= 
Date: Thu, 7 Mar 2024 23:04:22 +0100
Subject: [PATCH] [clang-repl] Add CreateJITBuilder() for specialization in
 derived classes

The LLJITBuilder interface provides a very convenient way to configure the JIT.
---
 clang/include/clang/Interpreter/Interpreter.h |   9 ++
 clang/lib/Interpreter/IncrementalExecutor.cpp |  33 ++---
 clang/lib/Interpreter/IncrementalExecutor.h   |   9 +-
 clang/lib/Interpreter/Interpreter.cpp |  26 +++-
 .../Interpreter/InterpreterExtensionsTest.cpp | 119 +-
 5 files changed, 175 insertions(+), 21 deletions(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 1dcba1ef967980..33ce4bbf5bea10 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -29,7 +29,9 @@
 
 namespace llvm {
 namespace orc {
+class JITTargetMachineBuilder;
 class LLJIT;
+class LLJITBuilder;
 class ThreadSafeContext;
 } // namespace orc
 } // namespace llvm
@@ -127,6 +129,13 @@ class Interpreter {
   // custom runtime.
   virtual std::unique_ptr FindRuntimeInterface();
 
+  // Lazily construct thev ORCv2 JITBuilder. This called when the internal
+  // IncrementalExecutor is created. The default implementation populates an
+  // in-process JIT with debugging support. Override this to configure the JIT
+  // engine used for execution.
+  virtual llvm::Expected>
+  CreateJITBuilder(CompilerInstance &CI);
+
 public:
   virtual ~Interpreter();
 
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 40bcef94797d43..6f036107c14a9c 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
@@ -36,26 +37,28 @@ LLVM_ATTRIBUTE_USED void linkComponents() {
 
 namespace clang {
 
+llvm::Expected>
+IncrementalExecutor::createDefaultJITBuilder(
+llvm::orc::JITTargetMachineBuilder JTMB) {
+  auto JITBuilder = std::make_unique();
+  JITBuilder->setJITTargetMachineBuilder(std::move(JTMB));
+  JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) {
+// Try to enable debugging of JIT'd code (only works with JITLink for
+// ELF and MachO).
+consumeError(llvm::orc::enableDebuggerSupport(J));
+return llvm::Error::success();
+  });
+  return std::move(JITBuilder);
+}
+
 IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
- llvm::Error &Err,
- const clang::TargetInfo &TI)
+ llvm::orc::LLJITBuilder &JITBuilder,
+ llvm::Error &Err)
 : TSCtx(TSC) {
   using namespace llvm::orc;
   llvm::ErrorAsOutParameter EAO(&Err);
 
-  auto JTMB = JITTargetMachineBuilder(TI.getTriple());
-  JTMB.addFeatures(TI.getTargetOpts().Features);
-  LLJITBuilder Builder;
-  Builder.setJITTargetMachineBuilder(JTMB);
-  Builder.setPrePlatformSetup(
-  [](LLJIT &J) {
-// Try to enable debugging of JIT'd code (only works with JITLink for
-// ELF and MachO).
-consumeError(enableDebuggerSupport(J));
-return llvm::Error::success();
-  });
-
-  if (auto JitOrErr = Builder.create())
+  if (auto JitOrErr = JITBuilder.create())
 Jit = std::move(*JitOrErr);
   else {
 Err = JitOrErr.takeError();
diff --git a/clang/lib/Interpreter/IncrementalExecutor.h 
b/clang/lib/Interpreter/IncrementalExecutor.h
index dd0a210a061415..b4347209e14fe3 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.h
+++ b/clang/lib/Interpreter/IncrementalExecutor.h
@@ -23,7 +23,9 @@
 namespace llvm {
 class Error;
 namespace orc {
+class JITTargetMachineBuilder;
 class LLJIT;
+class LLJITBuilder;
 class ThreadSafeContext;
 } // namespace orc
 } // namespace llvm
@@ -44,8 +46,8 @@ class IncrementalExecutor {
 public:
   enum SymbolNameKind { IRName, LinkerName };
 
-  IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, llvm::Error &Err,
-  const clang::TargetInfo &TI);
+  IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
+  llvm::orc::LLJITBuilder &JITBuilder, llvm::Error &Err);
   ~IncrementalExecutor();
 
   llvm::Error addModule(PartialTranslationUnit &PTU);
@@ -56,6 +58,9 @@ class IncrementalExecutor {
   getSymbolAddre

[clang] [clang-repl] Factor out CreateJITBuilder() and allow specialization in derived classes (PR #84461)

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

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


[clang] f03aaa3 - [clang] Silence -Wlogical-op-parentheses in Clang.cpp (NFC)

2024-03-12 Thread Jie Fu via cfe-commits

Author: Jie Fu
Date: 2024-03-12T21:24:37+08:00
New Revision: f03aaa3c0cca77c15adfbb4544f296bc0441f6fc

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

LOG: [clang] Silence -Wlogical-op-parentheses in Clang.cpp (NFC)

llvm-project/clang/lib/Driver/ToolChains/Clang.cpp:2721:49:
error: '&&' within '||' [-Werror,-Wlogical-op-parentheses]
!Option.empty() && !NegateFortranOption && !NegateLimitedOption)
^~~
llvm-project/clang/lib/Driver/ToolChains/Clang.cpp:2721:49:
note: place parentheses around the '&&' expression to silence this warning
!Option.empty() && !NegateFortranOption && !NegateLimitedOption)
^
(  )
1 error generated.

Added: 


Modified: 
clang/lib/Driver/ToolChains/Clang.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 6246a28a13060e..3a7a1cf99c79ac 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2718,7 +2718,7 @@ static void EmitComplexRangeDiag(const Driver &D,
   Option == "-fno-cx-limited-range";
 }
 if (Option.empty() ||
-!Option.empty() && !NegateFortranOption && !NegateLimitedOption)
+(!Option.empty() && !NegateFortranOption && !NegateLimitedOption))
   D.Diag(clang::diag::warn_drv_overriding_option)
   << EnumComplexRangeToStr(Range1, Option)
   << EnumComplexRangeToStr(Range2, Option);



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


[clang] [clang][ASTMatchers] Fix forEachArgumentWithParam* for deducing "this" operator calls (PR #84887)

2024-03-12 Thread Piotr Zegar via cfe-commits

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

Overall looks fine.

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


  1   2   3   4   5   >