[clang] [clang][Darwin] Remove legacy framework search path logic in the frontend (PR #75841)

2023-12-30 Thread Brad Smith via cfe-commits

brad0 wrote:

Update?

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


[lld] [clang] [llvm] [llvm-driver] Fix usage of `InitLLVM` on Windows (PR #76306)

2023-12-30 Thread Alexandre Ganea via cfe-commits

aganea wrote:

@MaskRay Can you please take another look?

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


[lld] [clang] [llvm] [llvm-driver] Fix usage of `InitLLVM` on Windows (PR #76306)

2023-12-30 Thread Alexandre Ganea via cfe-commits

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


[lld] [clang] [llvm] [llvm-driver] Fix usage of `InitLLVM` on Windows (PR #76306)

2023-12-30 Thread Alexandre Ganea via cfe-commits

https://github.com/aganea updated 
https://github.com/llvm/llvm-project/pull/76306

>From 8187e95ea4e04793fbfc85045aa21f9633bbc03d Mon Sep 17 00:00:00 2001
From: Alexandre Ganea 
Date: Sat, 23 Dec 2023 19:17:06 -0500
Subject: [PATCH 1/2] [llvm-driver] Fix tool re-entrance on Windows.

Previously, some tools such as `clang` or `lld` which require strict order for 
certain command-line options, such as `clang -cc1` or `lld -flavor` would not 
long work on Windows, when these tools were linked as part of `llvm-driver`. 
This was caused by `InitLLVM` which was part of the `main()` function of these 
tools, which in turn calls `windows::GetCommandLineArguments`. This function 
completly replaces argc/argv by new UTF-8 contents, so any ajustements to 
argc/argv made by `llvm-driver` prior to calling these tools would be reset.

We now call `InitLLVM` as part of the `llvm-driver`. Any further usages to 
`InitLLVM` on the stack, after the first call in the process would have no 
effect. In the same way, the last `InitLLVM` on the stack will clear the 
`ManagedStatics` as usual.
---
 llvm/cmake/modules/llvm-driver-template.cpp.in | 2 ++
 llvm/lib/Support/InitLLVM.cpp  | 6 ++
 llvm/tools/llvm-driver/llvm-driver.cpp | 6 +-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/llvm/cmake/modules/llvm-driver-template.cpp.in 
b/llvm/cmake/modules/llvm-driver-template.cpp.in
index 16c4fb34714638..71aca6cd140cb5 100644
--- a/llvm/cmake/modules/llvm-driver-template.cpp.in
+++ b/llvm/cmake/modules/llvm-driver-template.cpp.in
@@ -8,9 +8,11 @@
 
 #include "llvm/Support/LLVMDriver.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/InitLLVM.h"
 
 int @TOOL_NAME@_main(int argc, char **, const llvm::ToolContext &);
 
 int main(int argc, char **argv) {
+  llvm::InitLLVM X(argc, argv);
   return @TOOL_NAME@_main(argc, argv, {argv[0], nullptr, false});
 }
diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp
index 7f475f42f3cb81..2a2e6c254c795a 100644
--- a/llvm/lib/Support/InitLLVM.cpp
+++ b/llvm/lib/Support/InitLLVM.cpp
@@ -36,8 +36,12 @@ void CleanupStdHandles(void *Cookie) {
 using namespace llvm;
 using namespace llvm::sys;
 
+static std::atomic UsageCount{0};
+
 InitLLVM::InitLLVM(int , const char **,
bool InstallPipeSignalExitHandler) {
+  if (UsageCount++)
+return;
 #ifdef __MVS__
   // Bring stdin/stdout/stderr into a known state.
   sys::AddSignalHandler(CleanupStdHandles, nullptr);
@@ -94,6 +98,8 @@ InitLLVM::InitLLVM(int , const char **,
 }
 
 InitLLVM::~InitLLVM() {
+  if (--UsageCount)
+return;
 #ifdef __MVS__
   CleanupStdHandles(nullptr);
 #endif
diff --git a/llvm/tools/llvm-driver/llvm-driver.cpp 
b/llvm/tools/llvm-driver/llvm-driver.cpp
index a0f1ca831d93b6..53a8b9357e3780 100644
--- a/llvm/tools/llvm-driver/llvm-driver.cpp
+++ b/llvm/tools/llvm-driver/llvm-driver.cpp
@@ -10,6 +10,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/LLVMDriver.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/WithColor.h"
@@ -79,4 +80,7 @@ static int findTool(int Argc, char **Argv, const char *Argv0) 
{
   return 1;
 }
 
-int main(int Argc, char **Argv) { return findTool(Argc, Argv, Argv[0]); }
+int main(int Argc, char **Argv) {
+  llvm::InitLLVM X(Argc, Argv);
+  return findTool(Argc, Argv, Argv[0]);
+}

>From 03d24462dbc2e113bf0f740f3d95f519367c1abd Mon Sep 17 00:00:00 2001
From: Alexandre Ganea 
Date: Sat, 30 Dec 2023 22:45:58 -0500
Subject: [PATCH 2/2] Remove `InitLLVM` from all the tools participating in the
 `llvm-driver`.

---
 clang/tools/clang-scan-deps/ClangScanDeps.cpp |  2 --
 clang/tools/driver/driver.cpp |  2 --
 lld/Common/DriverDispatcher.cpp   |  1 -
 lld/tools/lld/lld.cpp |  2 --
 llvm/lib/Support/InitLLVM.cpp | 11 +--
 llvm/tools/dsymutil/dsymutil.cpp  |  3 ---
 llvm/tools/llvm-ar/llvm-ar.cpp|  2 --
 llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp  |  2 --
 llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp|  2 --
 llvm/tools/llvm-dwp/llvm-dwp.cpp  |  3 ---
 .../tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp |  2 --
 llvm/tools/llvm-lipo/llvm-lipo.cpp|  2 --
 llvm/tools/llvm-ml/llvm-ml.cpp|  2 --
 llvm/tools/llvm-mt/llvm-mt.cpp|  3 ---
 llvm/tools/llvm-nm/llvm-nm.cpp|  2 --
 llvm/tools/llvm-objcopy/llvm-objcopy.cpp  |  2 --
 llvm/tools/llvm-objdump/llvm-objdump.cpp  |  2 --
 llvm/tools/llvm-profdata/llvm-profdata.cpp|  2 --
 llvm/tools/llvm-rc/llvm-rc.cpp|  2 --
 llvm/tools/llvm-readobj/llvm-readobj.cpp  |  2 --
 

[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Max Winkler (MaxEW707)


Changes

There are code bases that inline `std::move` manually via `static_cast`.
Treat a static cast to an xvalue as an inlined `std::move` call and warn on a 
self move.

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaChecking.cpp (+14-5) 
- (modified) clang/test/SemaCXX/warn-self-move.cpp (+13) 


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(x);  // expected-warning{{explicitly moving}}
 x = std::move(other.x);
 other.x = std::move(x);
 other.x = std::move(other.x);  // expected-warning{{explicitly moving}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

``




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


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-30 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 created 
https://github.com/llvm/llvm-project/pull/76646

There are code bases that inline `std::move` manually via `static_cast`.
Treat a static cast to an xvalue as an inlined `std::move` call and warn on a 
self move.

>From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sat, 30 Dec 2023 22:00:38 -0500
Subject: [PATCH] Warn on self move for inlined static cast

---
 clang/lib/Sema/SemaChecking.cpp   | 19 ++-
 clang/test/SemaCXX/warn-self-move.cpp | 13 +
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(x);  // expected-warning{{explicitly moving}}
 x = std::move(other.x);
 other.x = std::move(x);
 other.x = std::move(other.x);  // expected-warning{{explicitly moving}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

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


[clang] [Driver][Solaris] Remove reachable llvm_unreachable (PR #76645)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Brad Smith (brad0)


Changes

Remove the llvm_unreachable from getSolarisLibSuffix(). The code path is
reachable. In the case of an unsupported architecture we're not worrying
about trying to actually find the library paths, and I don't think it
makes sense for the Driver to crash.

Fixes #58334

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


1 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Solaris.cpp (+1-2) 


``diff
diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp 
b/clang/lib/Driver/ToolChains/Solaris.cpp
index 9a9792d019d5ed..200ac46aa53409 100644
--- a/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -295,13 +295,12 @@ static StringRef getSolarisLibSuffix(const llvm::Triple 
) {
   switch (Triple.getArch()) {
   case llvm::Triple::x86:
   case llvm::Triple::sparc:
+  default:
 break;
   case llvm::Triple::x86_64:
 return "/amd64";
   case llvm::Triple::sparcv9:
 return "/sparcv9";
-  default:
-llvm_unreachable("Unsupported architecture");
   }
   return "";
 }

``




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


[clang] [Driver][Solaris] Remove reachable llvm_unreachable (PR #76645)

2023-12-30 Thread Brad Smith via cfe-commits

https://github.com/brad0 created https://github.com/llvm/llvm-project/pull/76645

Remove the llvm_unreachable from getSolarisLibSuffix(). The code path is
reachable. In the case of an unsupported architecture we're not worrying
about trying to actually find the library paths, and I don't think it
makes sense for the Driver to crash.

Fixes #58334

>From a79555f4f862a7717ce9e50973e9609bb5eadf97 Mon Sep 17 00:00:00 2001
From: Brad Smith 
Date: Sat, 30 Dec 2023 21:37:55 -0500
Subject: [PATCH] [Driver][Solaris] Remove reachable llvm_unreachable

Remove the llvm_unreachable from getSolarisLibSuffix(). The code path is
reachable. In the case of an unsupported architecture we're not worrying
about trying to actually find the library paths, and I don't think it
makes sense for the Driver to crash.

Fixes #58334
---
 clang/lib/Driver/ToolChains/Solaris.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp 
b/clang/lib/Driver/ToolChains/Solaris.cpp
index 9a9792d019d5ed..200ac46aa53409 100644
--- a/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -295,13 +295,12 @@ static StringRef getSolarisLibSuffix(const llvm::Triple 
) {
   switch (Triple.getArch()) {
   case llvm::Triple::x86:
   case llvm::Triple::sparc:
+  default:
 break;
   case llvm::Triple::x86_64:
 return "/amd64";
   case llvm::Triple::sparcv9:
 return "/sparcv9";
-  default:
-llvm_unreachable("Unsupported architecture");
   }
   return "";
 }

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


[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)

2023-12-30 Thread Max Winkler via cfe-commits

MaxEW707 wrote:

> I don't know whether all of these things should be handled with the same 
> attribute, or whether they should be handled at all, but they should 
> definitely be considered when designing this attribute.

For this I am more concerned with language level features such as move, 
forward, reserved placement operator new, etc and not all generic std 
functions. I can see where that becomes muddy.

For example `to_integer`, `to_underlying` or `identity::operator` I don't view 
as language level features that require a `std` implementation. I view them as 
a larger issue with high level operations being poorly represented by the 
language itself.
I would love `operator->` and `operator*` on smart pointers that just return a 
member variable to be replaced with a direct field access.
I would love for bitwise operators on enum class types to be replaced directly 
with the builtin bitwise operation on the underlying type instead of a function 
call.

I would love for `std::byte` to be a builtin type in the compiler like 
`char8_t` and not be implemented in the std with a special check inside clang 
for `isStdByte`. Thankfully we can workaround this with the `may_alias` 
attribute on clang for our own enum class byte type.

I would also love for `std::initializer_list` to be a builtin type without this 
delicate dance with the std and the compiler on specific signatures for the 
constructor. Look at how MSVC defines `std::initializer_list`.

I foresee the compiler increasing making assumptions about the names of 
functions and types inside the std namespace like `std::to_underlying`, 
`std::byte`, etc. `clang::behaves_like_std` gives users an easy to tell the 
compiler to make those same assumptions with user defined names.

There are cases where the std functions have other implicit properties. 
Reserved placement operator new can be assumed to not have to check the 
returned pointer for null. If you implement your own placement operator new you 
do not get this benefit. MSVC only removes this check for the reserved 
placement new but thankfully provides the define `__PLACEMENT_NEW_INLINE` if 
you decide to define it yourself. I believe you can work this with the 
`returns_nonnull` attribute on clang when I checked some months back. However 
clang still does the function call in debug if you are not the global reserved 
placement operator new which sucks.

Maybe for stuff like `operator->` on a smart pointer the compiler will start 
looking at `std::unique_ptr::operator->`.
Maybe for these facilities we instead have a more generic attribute like 
`[[clang::treat_as_macro]]` which more closely aligns with the semantics of 
`mvsc::intrinsic`.
Maybe we improve `always_inline` code gen for small functions like `std::move` 
and `operator->` on a object that just returns its member variable to have the 
same assembly in debug as if those functions were implemented like macros.

I haven't thought too much about those other cases yet but if `always_inline` 
on `MyMove` produced the same code in debug as `std::move` that gets me 90% of 
what I want and that would also probably fix all the other small function calls.
My 2c.

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


[libcxx] [flang] [clang-tools-extra] [llvm] [libc] [clang] [lldb] [compiler-rt] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Hristo Hristov via cfe-commits


@@ -26,7 +26,7 @@ template 
 void test_call_operator_forwarding() {
   using Fn = ForwardingCallObject;
   Fn obj{};
-  const Fn  = obj;

Zingam wrote:

The reason for reformatting both files is that the CI format check failed for 
nearly every line in the previous commit:
https://github.com/llvm/llvm-project/actions/runs/7362740090/job/20041480045

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


[clang] [Clang][Parser] Fix crash of clang when using C++ constructs like :: in C code (PR #74926)

2023-12-30 Thread via cfe-commits

ChipsSpectre wrote:

@tbaederr The build is fixed now. Can you merge the pull request?

Since I have no write access to llvm-project, it seems I can not do it on my 
own:

![Screenshot](https://github.com/llvm/llvm-project/assets/11499442/e0fb925f-a72a-4c1e-827f-cb39c99faa4c)


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


[clang] [Clang][Parser] Fix crash of clang when using C++ constructs like :: in C code (PR #74926)

2023-12-30 Thread via cfe-commits

https://github.com/ChipsSpectre updated 
https://github.com/llvm/llvm-project/pull/74926

>From cb46f3aab771133e3987c65bcbd1f6011792e74c Mon Sep 17 00:00:00 2001
From: ChipsSpectre 
Date: Sat, 30 Dec 2023 23:01:12 +0100
Subject: [PATCH] [clang][Parse] `TryAnnotateCXXScopeToken` to be called only
 when parsing C++

Assume `TryAnnotateCXXScopeToken` to be parsing C++ code in all of its paths.

Fixes: https://github.com/llvm/llvm-project/issues/73559.
---
 clang/docs/ReleaseNotes.rst  | 6 --
 clang/lib/Parse/ParseDecl.cpp| 3 ++-
 clang/lib/Parse/ParseDeclCXX.cpp | 2 ++
 clang/test/Parser/cxx-in-c.c | 3 +++
 4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0c8fec691bf3c9..da9b78b60bee8c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -685,9 +685,11 @@ Bug Fixes in This Version
   (`#65568 `_)
 - Fix an issue where clang doesn't respect detault template arguments that
   are added in a later redeclaration for CTAD.
-  Fixes (#69987 `_)
+  Fixes (`#69987 `_)
 - Fix an issue where CTAD fails for explicit type conversion.
-  Fixes (#64347 `_)
+  Fixes (`#64347 `_)
+- Fix crash when using C++ only tokens like ``::`` in C compiler clang.
+  Fixes (`#73559 https://github.com/llvm/llvm-project/issues/73559`_)
 
 
 Bug Fixes to Compiler Builtins
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index ed006f9d67de45..b60ae293ef8c20 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3483,7 +3483,8 @@ void Parser::ParseDeclarationSpecifiers(
 
 case tok::coloncolon: // ::foo::bar
   // C++ scope specifier.  Annotate and loop, or bail out on error.
-  if (TryAnnotateCXXScopeToken(EnteringContext)) {
+  if (getLangOpts().CPlusPlus &&
+  TryAnnotateCXXScopeToken(EnteringContext)) {
 if (!DS.hasTypeSpecifier())
   DS.SetTypeSpecError();
 goto DoneWithDeclSpec;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 910112ecae964c..d97081da4200de 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2679,6 +2679,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ParsedAttributes ,
const ParsedTemplateInfo ,
ParsingDeclRAIIObject *TemplateDiags) {
+  assert(getLangOpts().CPlusPlus &&
+ "ParseCXXClassMemberDeclaration should only be called in C++ mode");
   if (Tok.is(tok::at)) {
 if (getLangOpts().ObjC && NextToken().isObjCAtKeyword(tok::objc_defs))
   Diag(Tok, diag::err_at_defs_cxx);
diff --git a/clang/test/Parser/cxx-in-c.c b/clang/test/Parser/cxx-in-c.c
index f5fa39bd0cb99b..034a44cdf12bfa 100644
--- a/clang/test/Parser/cxx-in-c.c
+++ b/clang/test/Parser/cxx-in-c.c
@@ -3,3 +3,6 @@
 // PR9137
 void f0(int x) : {}; // expected-error{{expected function body after function 
declarator}}
 void f1(int x) try {}; // expected-error{{expected function body after 
function declarator}}
+
+// GH73559
+::; // expected-error{{expected identifier or '('}}

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


[clang-tools-extra] [libc] [llvm] [flang] [lldb] [libcxx] [clang] [compiler-rt] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Hristo Hristov via cfe-commits

https://github.com/H-G-Hristov edited 
https://github.com/llvm/llvm-project/pull/76447
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)

2023-12-30 Thread Max Winkler via cfe-commits

MaxEW707 wrote:

> (@MaxEW707 I think having a chat about this informally would be nice.)

Sounds good. Let me know the best way to contact you.

> While I disagree with the reasoning for not just using std

I'll try to give more context here. The main reason is include times and not 
wanting to work around a variety of vendor STLs who have widely different 
include times and behaviours.
For clang we need to worry about 5 different STLs: MSVC STL, libstdc++, libc++, 
a vendor STL and some vendor forks of libc++.
There are larger issues here when dealing with shipped vendor STLs that are 
custom or forks of libc++ that we can talk about offline.

On one of our smaller projects the PC build is ~16,000 cpp files which includes 
the generated cpp files, the tools, engine, tests, and the game itself. This is 
the build that most engineers work on and they usually need to work across a 
variety of domains since a change in the engine may require a change in the 
code generator, editor, asset building, the unit tests, the integration tests, 
etc.

On this smaller project one of our console builds which only includes the game 
itself is around ~4k source files when I last checked. Just adding `#include 
` to our `corelib/placement_new.h` header increased build times by ~22 
seconds. On this platform the vendor STL `` took 29ms to parse so that 
means that header was roughly included into ~750 files. That is a build time 
increase for one file include that we cannot at all live with.

We do not use the STL anywhere in our code base. We have our own so just 
including any STL header also brings in other headers like `type_traits` and 
their config headers. On MSVC STL it brings in `yvals_core.h` and its 
dependencies.
For us these headers are never amortized because a cpp file might use 
``, ``, ``, etc from the STL.

At the end of the day we don't want to deal with different STL implementations.
We do not use STL and do not want to include it.
We do not agree with a lot of language level features like move, placement new, 
etc being implemented in the std. We would prefer to just have compiler 
builtins for us like `__builtin_launder` and `__builtin_addressof`.
A lot of std headers also aren't small. `` is huge when I just need 
`move` and `forward`. `` is massive when I just need placement new because 
we do not at all ever hit global new. libc++ is getting better here, 
https://libcxx.llvm.org/DesignDocs/HeaderRemovalPolicy.html, but we still have 
to deal with MSVC STL, vendor STL and vendor forks of libc++.
We would rather just have compiler support that everyone can use instead of 
relying on the STL to implement language level features especially given how 
much the compiler is being asked to poke into the std lately.
In my view C++ should not require the STL to "work". I shouldn't need a library 
to use a language.

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


[clang] [clang][Interp] Fix nullptr array dereferencing (PR #75798)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Support __real/__imag on primitives (PR #75485)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Implement integral->complex casts (PR #75590)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Diagnose reads from non-const global variables (PR #71919)

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


tbaederr wrote:

Ping

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


[clang] [clang][Interp] IndirectMember initializers (PR #69900)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [Clang][Parser] Fix crash of clang when using C++ constructs like :: in C code (PR #74926)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

The build fails though, with this error:

``
tools/clang/docs/ReleaseNotes.rst:691:Unknown target name: "#73559 
https://github.com/llvm/llvm-project/issues/73559;
``

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


[clang] 8346e86 - [clang] Add build type to LibASTMatchersTutorial.rst cmake (#76301)

2023-12-30 Thread via cfe-commits

Author: Craig Hesling
Date: 2023-12-30T19:24:14+01:00
New Revision: 8346e8608f5eb7ad03f2c6beacda43af563b4eae

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

LOG: [clang] Add build type to LibASTMatchersTutorial.rst cmake (#76301)

Add the required CMAKE_BUILD_TYPE to the cmake configuration line.

We drop the comment about enabling tests, since it is already implied
and doesn't add any additional context.

Added: 


Modified: 
clang/docs/LibASTMatchersTutorial.rst

Removed: 




diff  --git a/clang/docs/LibASTMatchersTutorial.rst 
b/clang/docs/LibASTMatchersTutorial.rst
index 37c9f178fa8df3..2a58502a8de4e7 100644
--- a/clang/docs/LibASTMatchersTutorial.rst
+++ b/clang/docs/LibASTMatchersTutorial.rst
@@ -50,7 +50,7 @@ Okay. Now we'll build Clang!
 
   cd ~/clang-llvm
   mkdir build && cd build
-  cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" 
-DLLVM_BUILD_TESTS=ON  # Enable tests; default is off.
+  cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" 
-DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=ON
   ninja
   ninja check   # Test LLVM only.
   ninja clang-test  # Test Clang only.



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


[clang] [clang] Add build type to LibASTMatchersTutorial.rst cmake (PR #76301)

2023-12-30 Thread Timm Baeder via cfe-commits

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


[clang] [Clang][Parser] Fix crash of clang when using C++ constructs like :: in C code (PR #74926)

2023-12-30 Thread Timm Baeder via cfe-commits

tbaederr wrote:

It doesn't need a specific approval, just _any_. And @shafik has already 
approved this PR, so it can now be merged.

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


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Ding Fei (danix800)


Changes

Fixes #76425

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


2 Files Affected:

- (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+2) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (+2) 


``diff
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 82a26356c58f55..91c33e4b1163e6 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4817,6 +4817,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, 
internal::Matcher,
 /// capturesVar(hasName("x")) matches `x` and `x = 1`.
 AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher,
   InnerMatcher) {
+  if (!Node.capturesVariable())
+return false;
   auto *capturedVar = Node.getCapturedVar();
   return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
 }
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 8f0dd5602307c5..eb493f9c3050ac 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2308,6 +2308,8 @@ TEST_P(ASTMatchersTest, 
LambdaCaptureTest_BindsToCaptureOfVarDecl) {
   matches("int main() { int cc; auto f = [=](){ return cc; }; }", 
matcher));
   EXPECT_TRUE(
   matches("int main() { int cc; auto f = [&](){ return cc; }; }", 
matcher));
+  EXPECT_TRUE(matches(
+  "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
 }
 
 TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {

``




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


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2023-12-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/76619

Fixes #76425

>From b26fa2acfd4974d1c09eef408b4d6c2dcbb16479 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Sun, 31 Dec 2023 00:32:01 +0800
Subject: [PATCH] [ASTMatchers] fix captureVars assertion failure on
 capturesVariables

Fixes #76425
---
 clang/include/clang/ASTMatchers/ASTMatchers.h   | 2 ++
 clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 82a26356c58f55..91c33e4b1163e6 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4817,6 +4817,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, 
internal::Matcher,
 /// capturesVar(hasName("x")) matches `x` and `x = 1`.
 AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher,
   InnerMatcher) {
+  if (!Node.capturesVariable())
+return false;
   auto *capturedVar = Node.getCapturedVar();
   return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
 }
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 8f0dd5602307c5..eb493f9c3050ac 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2308,6 +2308,8 @@ TEST_P(ASTMatchersTest, 
LambdaCaptureTest_BindsToCaptureOfVarDecl) {
   matches("int main() { int cc; auto f = [=](){ return cc; }; }", 
matcher));
   EXPECT_TRUE(
   matches("int main() { int cc; auto f = [&](){ return cc; }; }", 
matcher));
+  EXPECT_TRUE(matches(
+  "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
 }
 
 TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {

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


[clang] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

2023-12-30 Thread Michael Maitland via cfe-commits

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


[clang] fa8347f - [Clang][RISCV] bfloat uses 'y' instead of 'b' (#76575)

2023-12-30 Thread via cfe-commits

Author: Michael Maitland
Date: 2023-12-30T11:31:26-05:00
New Revision: fa8347fbc602d78a7e4297aa83a686b62943d828

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

LOG: [Clang][RISCV] bfloat uses 'y' instead of 'b' (#76575)

Builtins.def says that bfloat should be represented by the 'y'
character, not the 'b' character. The 'b' character is specified to
represent boolean. The implementation currently uses 'b' correctly for
boolean and incorrectly re-uses 'b' for bfloat.

This was not caught since no builtins are emitted in
build/tools/clang/include/clang/Basic/riscv_sifive_vector_builtins.inc.
Don't know that we can test this without creating builtins that expose
this issue, although I'm not sure we really want to do that.

Added: 


Modified: 
clang/include/clang/Basic/riscv_sifive_vector.td
clang/include/clang/Basic/riscv_vector_common.td
clang/lib/Support/RISCVVIntrinsicUtils.cpp
clang/utils/TableGen/RISCVVEmitter.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/riscv_sifive_vector.td 
b/clang/include/clang/Basic/riscv_sifive_vector.td
index e19a34f7632fdc..0d471f6c554c22 100644
--- a/clang/include/clang/Basic/riscv_sifive_vector.td
+++ b/clang/include/clang/Basic/riscv_sifive_vector.td
@@ -109,7 +109,7 @@ multiclass RVVVFWMACCBuiltinSet> 
suffixes_prototypes> {
   Name = NAME,
   HasMasked = false,
   Log2LMUL = [-2, -1, 0, 1, 2] in
-defm NAME : RVVOutOp1Op2BuiltinSet;
+defm NAME : RVVOutOp1Op2BuiltinSet;
 }
 
 multiclass RVVVQMACCDODBuiltinSet> suffixes_prototypes> {

diff  --git a/clang/include/clang/Basic/riscv_vector_common.td 
b/clang/include/clang/Basic/riscv_vector_common.td
index 4036ce8e6903f4..040db6f0cdbfb0 100644
--- a/clang/include/clang/Basic/riscv_vector_common.td
+++ b/clang/include/clang/Basic/riscv_vector_common.td
@@ -41,7 +41,7 @@
 //   x: float16_t (half)
 //   f: float32_t (float)
 //   d: float64_t (double)
-//   b: bfloat16_t (bfloat16)
+//   y: bfloat16_t (bfloat16)
 //
 // This way, given an LMUL, a record with a TypeRange "sil" will cause the
 // definition of 3 builtins. Each type "t" in the TypeRange (in this example

diff  --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp 
b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
index bf47461b59e0ad..2de977a3dc720b 100644
--- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp
+++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
@@ -203,7 +203,7 @@ void RVVType::initBuiltinStr() {
 }
 break;
   case ScalarTypeKind::BFloat:
-BuiltinStr += "b";
+BuiltinStr += "y";
 break;
   default:
 llvm_unreachable("ScalarType is invalid!");

diff  --git a/clang/utils/TableGen/RISCVVEmitter.cpp 
b/clang/utils/TableGen/RISCVVEmitter.cpp
index da2a885ce8512f..d570bcae8d8636 100644
--- a/clang/utils/TableGen/RISCVVEmitter.cpp
+++ b/clang/utils/TableGen/RISCVVEmitter.cpp
@@ -151,7 +151,7 @@ static BasicType ParseBasicType(char c) {
   case 'd':
 return BasicType::Float64;
 break;
-  case 'b':
+  case 'y':
 return BasicType::BFloat16;
 break;
   default:



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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread Gábor Spaits via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};

spaits wrote:

I have not implemented the modeling of these functions yet. Looking at the 
semantics of these functions I should really do some modeling of them or at 
least "turn off" the checker when a one of these functions are used.

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread Gábor Spaits via cfe-commits


@@ -87,6 +85,28 @@ bool isStdVariant(const Type *Type) {
   return isStdType(Type, llvm::StringLiteral("variant"));
 }
 
+bool isStdAny(const Type *Type) {
+  return isStdType(Type, llvm::StringLiteral("any"));
+}
+
+bool isVowel(char a) {
+  switch (a) {
+  case 'a':
+  case 'e':
+  case 'i':
+  case 'o':
+  case 'u':
+return true;
+  default:
+return false;
+  }
+}
+
+llvm::StringRef indefiniteArticleBasedOnVowel(char a) {
+  if (isVowel(a))
+return "an";
+  return "a";
+}

spaits wrote:

I like the new sentence you suggested. I will replace the current warning text 
for this checker and for `std::variant` checker too.

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread Gábor Spaits via cfe-commits


@@ -58,6 +58,14 @@ void wontConfuseStdGets() {
 
////
 // std::get
 
////
+void stdGetType2() {

spaits wrote:

Oh, this test is not relevant. It is basically the same as the one after it. I 
was just doing some debugging to see how CSA handles different kinds of object 
constructions and forgot to remove it. I will remove it.

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


[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Pol M (Destroyerrrocket)


Changes

Summary:

This patch adds constexpr support for __builtin_shufflevector and 
__builtin_convertvector.

A small oddity encountered was that the arg to the intrinsics may be an lvalue 
without any sort of implicit cast of any kind. I solved this through the 
EvaluateVectorOrLValue function, which treats the lvalue as if it was in an 
rvalue cast, which gets me the desired vector.

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


4 Files Affected:

- (modified) clang/docs/LanguageExtensions.rst (+3-2) 
- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/lib/AST/ExprConstant.cpp (+137-1) 
- (modified) clang/test/Sema/constant-builtins-2.c (+61) 


``diff
diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 23a7f4f5d5b926..5f06c3d4b86f94 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2853,7 +2853,7 @@ Query for this feature with 
``__has_builtin(__builtin_dump_struct)``
 ``__builtin_shufflevector`` is used to express generic vector
 permutation/shuffle/swizzle operations.  This builtin is also very important
 for the implementation of various target-specific header files like
-.
+. This builtin can be used within constant expressions.
 
 **Syntax**:
 
@@ -2907,7 +2907,8 @@ Query for this feature with 
``__has_builtin(__builtin_shufflevector)``.
 
 ``__builtin_convertvector`` is used to express generic vector
 type-conversion operations. The input vector and the output vector
-type must have the same number of elements.
+type must have the same number of elements. This builtin can be used within
+constant expressions.
 
 **Syntax**:
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0c8fec691bf3c9..b6f1407436ed4f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -237,6 +237,8 @@ Non-comprehensive list of changes in this release
 * Since MSVC 19.33 added undocumented attribute ``[[msvc::constexpr]]``, this 
release adds the attribute as well.
 
 * Added ``#pragma clang fp reciprocal``.
+* Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may 
now be used within constant
+ expressions.
 
 New Compiler Flags
 --
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f6aeee1a4e935d..e8afa10fe7aaac 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2702,7 +2702,8 @@ static bool checkFloatingPointResult(EvalInfo , 
const Expr *E,
 static bool HandleFloatToFloatCast(EvalInfo , const Expr *E,
QualType SrcType, QualType DestType,
APFloat ) {
-  assert(isa(E) || isa(E));
+  assert(isa(E) || isa(E) ||
+ isa(E));
   llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
   APFloat::opStatus St;
   APFloat Value = Result;
@@ -10643,6 +10644,9 @@ namespace {
 bool VisitUnaryImag(const UnaryOperator *E);
 bool VisitBinaryOperator(const BinaryOperator *E);
 bool VisitUnaryOperator(const UnaryOperator *E);
+bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
+bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
+
 // FIXME: Missing: conditional operator (for GNU
 // conditional select), shufflevector, ExtVectorElementExpr
   };
@@ -10895,6 +10899,138 @@ bool VectorExprEvaluator::VisitUnaryOperator(const 
UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue , EvalInfo ,
+   const Expr *E, const QualType ) {
+  if (!Evaluate(Result, Info, E))
+return false;
+
+  if (Result.isLValue()) {
+// Source of the data is an lvalue; Manually handle the lvalue as if
+// it was an rvalue to get the current APValue.
+LValue LValueFound;
+LValueFound.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result)) {
+  return false;
+}
+  }
+
+  if (!Result.isVector()) {
+return false;
+  }
+  return true;
+}
+
+static bool handleVectorConversion(EvalInfo , const FPOptions FPO,
+   const Expr *E, QualType SourceTy,
+   QualType DestTy, APValue const ,
+   APValue ) {
+  if (SourceTy->isIntegerType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = APValue(APFloat(0.0));
+  return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
+  DestTy, Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(
+  HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
+  return true;
+}
+  } else if (SourceTy->isRealFloatingType()) {
+if 

[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2023-12-30 Thread via cfe-commits

github-actions[bot] wrote:

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

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

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

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

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

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

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

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


[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2023-12-30 Thread Pol M via cfe-commits

https://github.com/Destroyerrrocket created 
https://github.com/llvm/llvm-project/pull/76615

Summary:

This patch adds constexpr support for __builtin_shufflevector and 
__builtin_convertvector.

A small oddity encountered was that the arg to the intrinsics may be an lvalue 
without any sort of implicit cast of any kind. I solved this through the 
EvaluateVectorOrLValue function, which treats the lvalue as if it was in an 
rvalue cast, which gets me the desired vector.

>From cba67a73ea1e59eb8eeb4e702d77f329028f4c22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pol=20Marcet=20Sard=C3=A0?= 
Date: Sat, 30 Dec 2023 13:59:00 +0100
Subject: [PATCH] [clang] Constexpr for __builtin_shufflevector and
 __builtin_convertvector

Summary:

This patch adds constexpr support for __builtin_shufflevector
and __builtin_convertvector.

A small oddity encountered was that the arg to the intrinsics may be an
lvalue without any sort of implicit cast of any kind. I solved this
through the EvaluateVectorOrLValue function, which treats the lvalue as
if it was in an rvalue cast, which gets me the desired vector.
---
 clang/docs/LanguageExtensions.rst |   5 +-
 clang/docs/ReleaseNotes.rst   |   2 +
 clang/lib/AST/ExprConstant.cpp| 138 +-
 clang/test/Sema/constant-builtins-2.c |  61 
 4 files changed, 203 insertions(+), 3 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 23a7f4f5d5b926..5f06c3d4b86f94 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2853,7 +2853,7 @@ Query for this feature with 
``__has_builtin(__builtin_dump_struct)``
 ``__builtin_shufflevector`` is used to express generic vector
 permutation/shuffle/swizzle operations.  This builtin is also very important
 for the implementation of various target-specific header files like
-.
+. This builtin can be used within constant expressions.
 
 **Syntax**:
 
@@ -2907,7 +2907,8 @@ Query for this feature with 
``__has_builtin(__builtin_shufflevector)``.
 
 ``__builtin_convertvector`` is used to express generic vector
 type-conversion operations. The input vector and the output vector
-type must have the same number of elements.
+type must have the same number of elements. This builtin can be used within
+constant expressions.
 
 **Syntax**:
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0c8fec691bf3c9..b6f1407436ed4f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -237,6 +237,8 @@ Non-comprehensive list of changes in this release
 * Since MSVC 19.33 added undocumented attribute ``[[msvc::constexpr]]``, this 
release adds the attribute as well.
 
 * Added ``#pragma clang fp reciprocal``.
+* Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may 
now be used within constant
+ expressions.
 
 New Compiler Flags
 --
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f6aeee1a4e935d..e8afa10fe7aaac 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2702,7 +2702,8 @@ static bool checkFloatingPointResult(EvalInfo , 
const Expr *E,
 static bool HandleFloatToFloatCast(EvalInfo , const Expr *E,
QualType SrcType, QualType DestType,
APFloat ) {
-  assert(isa(E) || isa(E));
+  assert(isa(E) || isa(E) ||
+ isa(E));
   llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
   APFloat::opStatus St;
   APFloat Value = Result;
@@ -10643,6 +10644,9 @@ namespace {
 bool VisitUnaryImag(const UnaryOperator *E);
 bool VisitBinaryOperator(const BinaryOperator *E);
 bool VisitUnaryOperator(const UnaryOperator *E);
+bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
+bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
+
 // FIXME: Missing: conditional operator (for GNU
 // conditional select), shufflevector, ExtVectorElementExpr
   };
@@ -10895,6 +10899,138 @@ bool VectorExprEvaluator::VisitUnaryOperator(const 
UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue , EvalInfo ,
+   const Expr *E, const QualType ) {
+  if (!Evaluate(Result, Info, E))
+return false;
+
+  if (Result.isLValue()) {
+// Source of the data is an lvalue; Manually handle the lvalue as if
+// it was an rvalue to get the current APValue.
+LValue LValueFound;
+LValueFound.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result)) {
+  return false;
+}
+  }
+
+  if (!Result.isVector()) {
+return false;
+  }
+  return true;
+}
+
+static bool handleVectorConversion(EvalInfo , const FPOptions FPO,
+   const Expr *E, QualType SourceTy,
+

[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)

2023-12-30 Thread Nikolas Klauser via cfe-commits


@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+namespace mystd {
+inline namespace bar {
+template  struct remove_reference { typedef T type; };
+template  struct remove_reference { typedef T type; };
+template  struct remove_reference { typedef T type; };

philnik777 wrote:

Maybe just use `__remove_reference_t`?

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


[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)

2023-12-30 Thread Nikolas Klauser via cfe-commits

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


[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)

2023-12-30 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 commented:

While I disagree with the reasoning for not just using `std` (@MaxEW707 I think 
having a chat about this informally would be nice.), I do think it makes sense 
to add the ability to declare some functions as builtins. There are a few cases 
inside the standard library itself:
- simply allowing the same optimizations to be done with `-ffreestanding`
- there are quite a few more functions which behave just like builtins, but are 
currently not recognized as such by the compiler. e.g. `identity::operator()`
- library-internal functionality which would have to be handled by the compiler 
for every implementation, like `__identity::operator()` in libc++

The above ones are all handled by what is currently proposed, but there is also 
functionality which doesn't work with this proposal. For example:
- allowing the declaration of non-`std` builtins, like 
`char_traits::find()`, which could be declared as equivalent to 
`__builtin_memchr`.
- other functions which are essentially casts, but take their arguments 
by-value, like `to_underlying`
- Functions that are essentially builtin operations, like 
`char_traits::eq`

I don't know whether all of these things should be handled with the same 
attribute, or whether they should be handled at all, but they should definitely 
be considered when designing this attribute.


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


[flang] [llvm] [lldb] [compiler-rt] [clang-tools-extra] [libc] [clang] [libcxx] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -1273,6 +1280,15 @@ public:
 __impl_.__swap(__that.__impl_);
   }
 
+#  if _LIBCPP_STD_VER >= 26
+  // [variant.visit], visitation
+  template 
+  constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor);

mordante wrote:

nowadays we prefer to write the body in the class.

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


[libcxx] [llvm] [libc] [lldb] [compiler-rt] [clang-tools-extra] [clang] [flang] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -26,7 +26,7 @@ template 
 void test_call_operator_forwarding() {
   using Fn = ForwardingCallObject;
   Fn obj{};
-  const Fn  = obj;

mordante wrote:

Please undo the formatting changes to this file. It's hard to see what really 
changed.

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


[flang] [clang] [lldb] [libc] [libcxx] [llvm] [compiler-rt] [clang-tools-extra] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -0,0 +1,268 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// 
+
+// class variant;
+
+// template
+//   constexpr decltype(auto) visit(this Self&&, Visitor&&); // since C++26
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "variant_test_helpers.h"
+
+void test_call_operator_forwarding() {
+  using Fn = ForwardingCallObject;
+  Fn obj{};
+  const Fn& cobj = obj;
+
+  { // test call operator forwarding - no variant
+// non-member
+{
+  std::visit(obj);
+  assert(Fn::check_call<>(CT_NonConst | CT_LValue));

mordante wrote:

I assume this code is copied from somewhere else. I find it quite hard to read 
what is tested here.

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


[llvm] [compiler-rt] [libc] [clang] [libcxx] [flang] [clang-tools-extra] [lldb] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -17,27 +17,28 @@
 #include "test_macros.h"
 
 struct Incomplete;
-template struct Holder { T t; };

mordante wrote:

For this file too.

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


[libc] [clang] [clang-tools-extra] [libcxx] [compiler-rt] [lldb] [llvm] [flang] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -69,6 +69,12 @@ namespace std {
 
 // 20.7.2.6, swap
 void swap(variant&) noexcept(see below);
+
+// [variant.visit], visitation
+template
+  constexpr decltype(auto) visit(this Self&&, Visitor&&);
+template
+  constexpr R visit(this Self&&, Visitor&&);

mordante wrote:

```suggestion
template
  constexpr decltype(auto) visit(this Self&&, Visitor&&);// Since C++26
template
  constexpr R visit(this Self&&, Visitor&&); // Since C++26
```

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


[libc] [llvm] [libcxx] [clang-tools-extra] [flang] [clang] [lldb] [compiler-rt] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -0,0 +1,268 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// 
+
+// class variant;
+
+// template
+//   constexpr decltype(auto) visit(this Self&&, Visitor&&); // since C++26
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "variant_test_helpers.h"
+
+void test_call_operator_forwarding() {
+  using Fn = ForwardingCallObject;
+  Fn obj{};
+  const Fn& cobj = obj;
+
+  { // test call operator forwarding - no variant
+// non-member
+{
+  std::visit(obj);
+  assert(Fn::check_call<>(CT_NonConst | CT_LValue));
+  std::visit(cobj);
+  assert(Fn::check_call<>(CT_Const | CT_LValue));
+  std::visit(std::move(obj));
+  assert(Fn::check_call<>(CT_NonConst | CT_RValue));
+  std::visit(std::move(cobj));
+  assert(Fn::check_call<>(CT_Const | CT_RValue));
+}
+  }
+  { // test call operator forwarding - single variant, single arg
+using V = std::variant;
+V v(42);
+
+v.visit(obj);
+assert(Fn::check_call(CT_NonConst | CT_LValue));
+v.visit(cobj);
+assert(Fn::check_call(CT_Const | CT_LValue));
+v.visit(std::move(obj));
+assert(Fn::check_call(CT_NonConst | CT_RValue));
+v.visit(std::move(cobj));
+assert(Fn::check_call(CT_Const | CT_RValue));
+  }
+  { // test call operator forwarding - single variant, multi arg
+using V = std::variant;
+V v(42L);
+
+v.visit(obj);
+assert(Fn::check_call(CT_NonConst | CT_LValue));
+v.visit(cobj);
+assert(Fn::check_call(CT_Const | CT_LValue));
+v.visit(std::move(obj));
+assert(Fn::check_call(CT_NonConst | CT_RValue));
+v.visit(std::move(cobj));
+assert(Fn::check_call(CT_Const | CT_RValue));
+  }
+}
+
+// Applies to non-member `std::visit` only.
+void test_argument_forwarding() {
+  using Fn = ForwardingCallObject;
+  Fn obj{};
+  const auto val = CT_LValue | CT_NonConst;
+
+  { // single argument - value type
+using V = std::variant;
+V v(42);
+const V& cv = v;
+
+v.visit(obj);
+assert(Fn::check_call(val));
+cv.visit(obj);
+assert(Fn::check_call(val));
+std::move(v).visit(obj);
+assert(Fn::check_call(val));
+std::move(cv).visit(obj);
+assert(Fn::check_call(val));
+  }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+  { // single argument - lvalue reference
+using V = std::variant;
+int x   = 42;
+V v(x);
+const V& cv = v;
+
+v.visit(obj);
+assert(Fn::check_call(val));
+cv.visit(obj);
+assert(Fn::check_call(val));
+std::move(v).visit(obj);
+assert(Fn::check_call(val));
+std::move(cv).visit(obj);
+assert(Fn::check_call(val));
+assert(false);
+  }
+  { // single argument - rvalue reference
+using V = std::variant;
+int x   = 42;
+V v(std::move(x));
+const V& cv = v;
+
+v.visit(obj);
+assert(Fn::check_call(val));
+cvstd::visit(obj);
+assert(Fn::check_call(val));
+std::move(v).visit(obj);
+assert(Fn::check_call(val));
+std::move(cv).visit(obj);
+assert(Fn::check_call(val));
+  }
+#endif
+}
+
+void test_return_type() {
+  using Fn = ForwardingCallObject;
+  Fn obj{};
+  const Fn& cobj = obj;
+
+  { // test call operator forwarding - single variant, single arg
+using V = std::variant;
+V v(42);
+
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+  }
+  { // test call operator forwarding - single variant, multi arg
+using V = std::variant;
+V v(42L);
+
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+static_assert(std::is_same_v);
+  }
+}
+
+void test_constexpr() {
+  constexpr ReturnFirst obj{};
+
+  {
+using V = std::variant;
+constexpr V v(42);
+
+static_assert(v.visit(obj) == 42);
+  }
+  {
+using V = std::variant;
+constexpr V v(42L);
+
+static_assert(v.visit(obj) == 42);
+  }
+}
+
+void test_exceptions() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  ReturnArity obj{};
+
+  auto test = [&](auto&& v) {
+try {
+  v.visit(obj);
+} catch (const std::bad_variant_access&) {
+  return true;
+} catch (...) {
+}
+return false;
+  };
+
+  {
+using V = std::variant;
+V v;
+makeEmpty(v);
+
+assert(test(v));
+  }
+#endif
+}
+
+// See https://llvm.org/PR31916
+void test_caller_accepts_nonconst() {
+  struct A {};
+  struct Visitor {
+void operator()(A&) {}
+  };
+  std::variant v;
+
+  v.visit(Visitor{});
+}
+
+struct MyVariant : std::variant {};
+

[llvm] [clang-tools-extra] [libcxx] [compiler-rt] [libc] [flang] [lldb] [clang] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits


@@ -40,6 +40,8 @@ Paper Status
 .. note::
 
.. [#note-P2510R3] This paper is applied as DR against C++20. (MSVC STL and 
libstdc++ will do the same.)
+   .. [#note-P2637R3] P2637R3: Implemented `variant` member `visit`

mordante wrote:

Since we have both patches under review I don't mind to strongly about this 
note. It's more important when there a no other patches. (However I don't 
object.)

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


[llvm] [clang] [compiler-rt] [clang-tools-extra] [flang] [libc] [libcxx] [lldb] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits

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

Thanks for working on this!

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


[llvm] [clang-tools-extra] [libcxx] [flang] [compiler-rt] [libc] [clang] [lldb] [libc++][variant] P2637R3: Member `visit` (`std::variant`) (PR #76447)

2023-12-30 Thread Mark de Wever via cfe-commits

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);
+  }
+
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is ether a const reference or a right value reference.
+// We need the type referred.
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();
+if (!isStdAny(ArgType))
+  return false;
+
+const auto *AnyMemRegion = ArgSVal.getAsRegion();
+
+if (!State->contains(AnyMemRegion))
+  return false;
+
+// Get the type we are trying to retrieve from any.
+ 

[clang] [clang][modules] Print library module manifest path. (PR #76451)

2023-12-30 Thread Boris Kolpackov via cfe-commits

boris-kolpackov wrote:

> I had looked at `-print-search-dirs` but it seems buggy. For example, it 
> ignores the `-stdlib` flag to the compiler invocation. 

True. I couldn't find a bug report for this so I filed one: 
https://github.com/llvm/llvm-project/issues/76614

> Solving this seems a lot of work. So didn't want to add new features to that 
> code.

If this is the right thing to do (i.e., printing this information as part of 
`-print-search-dirs`), then perhaps it's still worth it to try and fix? Once 
you add a separate option, you will have to drag it forever (for backwards 
compatibility).

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};

whisperity wrote:

What about ` any::emplace(Ts&&...)` and `any::swap`?

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -2095,6 +2095,27 @@ This checker is a part of ``core.StackAddressEscape``, 
but is temporarily disabl
  //   returned block
  }
 
+.. _alpha-core-StdAny:
+
+alpha.core.StdAny (C++)
+"""
+Check if a value of active type is retrieved from an ``std::any`` instance 
with ``std::any_cats``
+or if the ``std::any`` instance holds type. In case of bad any type access
+(the accessed type differs from the active type, or the instance has no stored 
value)
+a warning is emitted. Currently, this checker does not take exception handling 
into account.

whisperity wrote:

```suggestion
Check if a value of active type is retrieved from a ``std::any`` instance with 
``std::any_cast``
or if the instance holds a value. In case of bad access
(the accessed type differs from the active type, or the instance is empty)
a warning is emitted.

**Limitation:** The checker does not take exception handling into account.
```

(+ reflow the lines)

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.

whisperity wrote:

```suggestion
  // When a std::any is reset or default constructed it has a null type.
  // We represent it by storing an empty QualType.
```

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,201 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  BugType BadAnyType{this, "BadAnyType", "BadAnyType"};
+  BugType NullAnyType{this, "NullAnyType", "NullAnyType"};
+
+public:
+  ProgramStateRef
+  checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *Invalidated,
+ ArrayRef ExplicitRegions,
+ ArrayRef Regions,
+ const LocationContext *LCtx, const CallEvent *Call) const 
{
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  setNullTypeAny(ThisMemRegion, C);
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // default constructor call
+  // in this case the any holds a null type
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+setNullTypeAny(ThisMemRegion, C);
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  void setNullTypeAny(const MemRegion *Mem, CheckerContext ) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is aether a const reference or a right value reference
+//  We need the type referred
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();

whisperity wrote:

I guess `getTypePtr()` alone should be safe, but there are *at least* two 
potentially unsafe dereferences here, the `getTypePtr()->` and the 
`getPointeeType().` Looking scary... 

Are we sure we will always get constructs that are dereferenceable this many 
times, in this particular order?
Wouldn't it be worth at least adding some intermediate asserts, just to make 
sure if 

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,201 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  BugType BadAnyType{this, "BadAnyType", "BadAnyType"};
+  BugType NullAnyType{this, "NullAnyType", "NullAnyType"};
+
+public:
+  ProgramStateRef
+  checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *Invalidated,
+ ArrayRef ExplicitRegions,
+ ArrayRef Regions,
+ const LocationContext *LCtx, const CallEvent *Call) const 
{
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  setNullTypeAny(ThisMemRegion, C);
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // default constructor call
+  // in this case the any holds a null type
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+setNullTypeAny(ThisMemRegion, C);
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  void setNullTypeAny(const MemRegion *Mem, CheckerContext ) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is aether a const reference or a right value reference
+//  We need the type referred
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();
+if (!isStdAny(ArgType))
+  return false;
+
+const auto *AnyMemRegion = ArgSVal.getAsRegion();
+
+if (!State->contains(AnyMemRegion))
+  return false;
+
+// get the type we are trying to get from any
+const CallExpr *CE = cast(Call.getOriginExpr());
+const FunctionDecl *FD = CE->getDirectCallee();

whisperity wrote:

(Think the `cast` should assert both when the 

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -30,6 +24,9 @@ bool isMoveAssignmentCall(const CallEvent );
 bool isMoveConstructorCall(const CallEvent );
 bool isStdType(const Type *Type, const std::string );
 bool isStdVariant(const Type *Type);
+bool isStdAny(const Type *Type);

whisperity wrote:

```suggestion
bool isStdAny(const Type *Type);
bool isStdVariant(const Type *Type);
```

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);
+  }
+
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is ether a const reference or a right value reference.
+// We need the type referred.
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();
+if (!isStdAny(ArgType))
+  return false;
+
+const auto *AnyMemRegion = ArgSVal.getAsRegion();
+
+if (!State->contains(AnyMemRegion))
+  return false;
+
+// Get the type we are trying to retrieve from any.
+ 

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -58,6 +58,14 @@ void wontConfuseStdGets() {
 
////
 // std::get
 
////
+void stdGetType2() {

whisperity wrote:

(Style nit: if this is `2`, move it below the other one?)

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);
+  }
+
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is ether a const reference or a right value reference.

whisperity wrote:

```suggestion
// The argument is either a const reference or a right value reference.
```

But is this guaranteed?

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -87,6 +85,28 @@ bool isStdVariant(const Type *Type) {
   return isStdType(Type, llvm::StringLiteral("variant"));
 }
 
+bool isStdAny(const Type *Type) {
+  return isStdType(Type, llvm::StringLiteral("any"));
+}
+
+bool isVowel(char a) {
+  switch (a) {
+  case 'a':
+  case 'e':
+  case 'i':
+  case 'o':
+  case 'u':
+return true;
+  default:
+return false;
+  }
+}
+
+llvm::StringRef indefiniteArticleBasedOnVowel(char a) {
+  if (isVowel(a))
+return "an";
+  return "a";
+}

whisperity wrote:

I don't think this is phonetically correct. For example, if I call this for the 
first letter in the word `union`, which is pronounced as [`YUU-ni-yon` or 
`YUUN-jen`](http://en.wiktionary.org/wiki/union#English), then it should be 
**`a union`** and not `an union`.

Some more examples: 
http://english.stackexchange.com/questions/266309/why-is-union-an-exception-to-the-a-an-rule

Might be worthwhile to just get rid of this altogether, and refactor the call 
site like this: `any held a value of 'Union'` or `any contained object of type 
'Union'`.

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);
+  }
+
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is ether a const reference or a right value reference.
+// We need the type referred.
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();
+if (!isStdAny(ArgType))
+  return false;
+
+const auto *AnyMemRegion = ArgSVal.getAsRegion();
+
+if (!State->contains(AnyMemRegion))
+  return false;
+
+// Get the type we are trying to retrieve from any.
+ 

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);

whisperity wrote:

Stale comment?

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};

whisperity wrote:

What about ` std::make_any(Ts&&...)`? I guess that one will call the 
constructor internally, so no problem here?

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,170 @@
+// RUN: %clang %s -std=c++17 -Xclang -verify --analyze \
+// RUN:   -Xclang -analyzer-checker=core \
+// RUN:   -Xclang -analyzer-checker=debug.ExprInspection \
+// RUN:   -Xclang -analyzer-checker=core,alpha.core.StdAny
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+void clang_analyzer_warnIfReached();
+void clang_analyzer_eval(int);
+
+
+class DummyClass{
+  public:
+  void foo(){};
+};
+
+void nonInlined(std::any );
+void nonInlinedConst(const std::any & a);
+
+void inlined(std::any ) {
+  a = 5;
+}
+
+using any_t = std::any;
+using any_tt = any_t;
+
+
+////
+// std::any_cast
+////
+void objectHeld() {
+  std::any a = DummyClass{};
+  DummyClass d = std::any_cast(a);
+  d.foo();
+}
+
+void formVariable() {
+  std::any a = 5;
+  int b = std::any_cast(a);
+  char c = std::any_cast(a); // expected-warning {{std::any 'a' held an 
'int', not a 'char'}}
+  (void)b;
+  (void)c;
+}
+
+void pointerHeld() {
+  int i = 5;
+  std::any a = 
+  int* x = std::any_cast(a);
+  char c = std::any_cast(a); // expected-warning {{std::any 'a' held an 
'int *', not a 'char'}}

whisperity wrote:

(Yeah, back to the vowel/pronounciation stuff, this reads correctly if you say 
`held an «int star»` but breaks apart if one meticulously wants to read this 
out as `held an «pointer to int object»`...)

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


[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits


@@ -0,0 +1,200 @@
+//===- StdAnyChecker.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
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tagged_union_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(AnyHeldTypeMap, const MemRegion *, QualType)
+
+class StdAnyChecker : public Checker {
+  CallDescription AnyConstructor{{"std", "any", "any"}};
+  CallDescription AnyAsOp{{"std", "any", "operator="}};
+  CallDescription AnyReset{{"std", "any", "reset"}, 0, 0};
+  CallDescription AnyCast{{"std", "any_cast"}, 1, 1};
+
+  const BugType BadAnyType{this, "Bad std::any type access.", "BadAnyType"};
+  const BugType NullAnyType{this, "std::any has no value", "NullAnyType"};
+
+public:
+  ProgramStateRef checkRegionChanges(ProgramStateRef State,
+ const InvalidatedSymbols *,
+ ArrayRef,
+ ArrayRef Regions,
+ const LocationContext *,
+ const CallEvent *Call) const {
+if (!Call)
+  return State;
+
+return removeInformationStoredForDeadInstances(*Call, 
State,
+   Regions);
+  }
+
+  bool evalCall(const CallEvent , CheckerContext ) const {
+// Do not take implementation details into consideration
+if (Call.isCalledFromSystemHeader())
+  return false;
+
+if (AnyCast.matches(Call))
+  return handleAnyCastCall(Call, C);
+
+if (AnyReset.matches(Call)) {
+  const auto *AsMemberCall = dyn_cast();
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  C.addTransition(setNullTypeAny(ThisMemRegion, C));
+  return true;
+}
+
+bool IsAnyConstructor =
+isa(Call) && AnyConstructor.matches(Call);
+bool IsAnyAssignmentOperatorCall =
+isa(Call) && AnyAsOp.matches(Call);
+
+if (IsAnyConstructor || IsAnyAssignmentOperatorCall) {
+  auto State = C.getState();
+  SVal ThisSVal = [&]() {
+if (IsAnyConstructor) {
+  const auto *AsConstructorCall = dyn_cast();
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast();
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();
+
+  // Default constructor call.
+  // In this case the any holds a null type.
+  if (Call.getNumArgs() == 0) {
+const auto *ThisMemRegion = ThisSVal.getAsRegion();
+C.addTransition(setNullTypeAny(ThisMemRegion, C));
+return true;
+  }
+
+  if (Call.getNumArgs() != 1)
+return false;
+
+  handleConstructorAndAssignment(Call, C, ThisSVal);
+  return true;
+}
+return false;
+  }
+
+private:
+  // When an std::any is rested or default constructed it has a null type.
+  // We represent it by storing a null QualType.
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem, CheckerContext ) 
const {
+auto State = C.getState();
+return State->set(Mem, QualType{});
+//C.addTransition(State);
+  }
+
+  bool handleAnyCastCall(const CallEvent , CheckerContext ) const {
+auto State = C.getState();
+
+if (Call.getNumArgs() != 1)
+  return false;
+
+auto ArgSVal = Call.getArgSVal(0);
+
+// The argument is ether a const reference or a right value reference.
+// We need the type referred.
+const auto *ArgType = ArgSVal.getType(C.getASTContext())
+  .getTypePtr()
+  ->getPointeeType()
+  .getTypePtr();
+if (!isStdAny(ArgType))
+  return false;
+
+const auto *AnyMemRegion = ArgSVal.getAsRegion();
+
+if (!State->contains(AnyMemRegion))
+  return false;
+
+// Get the type we are trying to retrieve from any.
+ 

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits

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


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


[clang] [llvm] [Clang][IR] add TBAA metadata on pointer, union and array types. (PR #75177)

2023-12-30 Thread Florian Hahn via cfe-commits

fhahn wrote:

Thanks for working on this! I think it would be good to split this up into 
multiple distinct parts for the different improvements.

I put up a patch to support distinct metadata for distinct pointers a while 
ago, which I just moved to GH: #76261.

The discussion on Phabricator has some interesting points and one of the 
concerns was that it is very difficult already to detect type violations in 
source code, which makes adopting more powerful TBAA features quite difficult. 
There are some tooling improvements we can make here, including a sanitizer for 
types, which would be good to get rolling again, see 
https://discourse.llvm.org/t/reviving-typesanitizer-a-sanitizer-to-catch-type-based-aliasing-violations/66092

TBAA union support and potential issues have been discussed in detail a number 
of years ago on the old mailing list (llvm-dev), did you have a look at those 
threads? 

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


[clang] [TBAA] Emit distinct TBAA tags for pointers with different depths,types. (PR #76612)

2023-12-30 Thread Florian Hahn via cfe-commits

fhahn wrote:

Move this over from Phabricator, see https://reviews.llvm.org/D122573 
http://108.170.204.19/D122573 for context.

Type sanitizer patches have been moved to GH as well: #76259, #76260, #76261

https://discourse.llvm.org/t/reviving-typesanitizer-a-sanitizer-to-catch-type-based-aliasing-violations/66092/

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


[clang] [TBAA] Emit distinct TBAA tags for pointers with different depths,types. (PR #76612)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Florian Hahn (fhahn)


Changes

This patch extends Clang's TBAA generation code to emit distinct tags for 
incompatible pointer types.

Pointers with different element types are incompatible if the pointee types are 
also incompatible (modulo sugar/modifiers).

Express this in TBAA by generating different tags for pointers based on the 
pointer depth and pointee type. To get the TBAA tag for the pointee type it 
uses getTypeInfoHelper on the pointee type.

(Moved from https://reviews.llvm.org/D122573)

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


2 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+25-4) 
- (modified) clang/test/CodeGen/tbaa-pointers.c (+42-30) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index dc288bc3f6157a..b96f9d28c45530 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -184,10 +184,31 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type 
*Ty) {
 return getChar();
 
   // Handle pointers and references.
-  // TODO: Implement C++'s type "similarity" and consider dis-"similar"
-  // pointers distinct.
-  if (Ty->isPointerType() || Ty->isReferenceType())
-return createScalarTypeNode("any pointer", getChar(), Size);
+  if (Ty->isPointerType() || Ty->isReferenceType()) {
+llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), 
Size);
+// Compute the depth of the pointer and generate a tag of the form 
"p
+// ".
+unsigned PtrDepth = 0;
+do {
+  PtrDepth++;
+  Ty = Ty->getPointeeType().getTypePtr();
+} while (Ty->isPointerType() || Ty->isReferenceType());
+// TODO: Implement C++'s type "similarity" and consider dis-"similar"
+// pointers distinct for non-builtin types.
+if (isa(Ty)) {
+  llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
+  StringRef Name =
+  cast(
+  ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
+  ->getString();
+  SmallString<256> OutName("p");
+  OutName += std::to_string(PtrDepth);
+  OutName += " ";
+  OutName += Name;
+  return createScalarTypeNode(OutName, AnyPtr, Size);
+}
+return AnyPtr;
+  }
 
   // Accesses to arrays are accesses to objects of their element types.
   if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
diff --git a/clang/test/CodeGen/tbaa-pointers.c 
b/clang/test/CodeGen/tbaa-pointers.c
index b9ebe879820012..a3a7aa0d66473e 100644
--- a/clang/test/CodeGen/tbaa-pointers.c
+++ b/clang/test/CodeGen/tbaa-pointers.c
@@ -4,9 +4,9 @@ void p2unsigned(unsigned **ptr) {
   // CHECK-LABEL: define void @p2unsigned(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:  %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0:!.+]]
-  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa 
[[ANY_POINTER_0]]
+  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0:!.+]]
+  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[P2INT_0]]
+  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]]
   // CHECK-NEXT:  ret void
   //
   *ptr = 0;
@@ -16,9 +16,9 @@ void p2unsigned_volatile(unsigned *volatile *ptr) {
   // CHECK-LABEL: define void @p2unsigned_volatile(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa 
[[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[P2INT_0]]
+  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa 
[[P1INT_0]]
   // CHECK-NEXT:   ret void
   //
   *ptr = 0;
@@ -28,10 +28,10 @@ void p3int(int ***ptr) {
   // CHECK-LABEL: define void @p3int(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE_1]], align 8, !tbaa 
[[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[P3INT_0:!.+]]
+  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[P3INT_0]]
+  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa 

[clang] [TBAA] Emit distinct TBAA tags for pointers with different depths,types. (PR #76612)

2023-12-30 Thread Florian Hahn via cfe-commits

https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/76612

This patch extends Clang's TBAA generation code to emit distinct tags for 
incompatible pointer types.

Pointers with different element types are incompatible if the pointee types are 
also incompatible (modulo sugar/modifiers).

Express this in TBAA by generating different tags for pointers based on the 
pointer depth and pointee type. To get the TBAA tag for the pointee type it 
uses getTypeInfoHelper on the pointee type.

(Moved from https://reviews.llvm.org/D122573)

>From 18f45a0b989d90a0f649dcc7b00f05be58fbe0c9 Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Sat, 30 Dec 2023 10:39:58 +
Subject: [PATCH] [TBAA] Emit distinct TBAA tags for pointers with different
 depths,types.

This patch extends Clang's TBAA generation code to emit distinct tags
for incompatible pointer types.

Pointers with different element types are incompatible if the pointee
types are also incompatible (modulo sugar/modifiers).

Express this in TBAA by generating different tags for pointers based
on the pointer depth and pointee type. To get the TBAA tag for the
pointee type it uses getTypeInfoHelper on the pointee type.

(Moved from https://reviews.llvm.org/D122573)
---
 clang/lib/CodeGen/CodeGenTBAA.cpp  | 29 ++--
 clang/test/CodeGen/tbaa-pointers.c | 72 +-
 2 files changed, 67 insertions(+), 34 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index dc288bc3f6157a..b96f9d28c45530 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -184,10 +184,31 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type 
*Ty) {
 return getChar();
 
   // Handle pointers and references.
-  // TODO: Implement C++'s type "similarity" and consider dis-"similar"
-  // pointers distinct.
-  if (Ty->isPointerType() || Ty->isReferenceType())
-return createScalarTypeNode("any pointer", getChar(), Size);
+  if (Ty->isPointerType() || Ty->isReferenceType()) {
+llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), 
Size);
+// Compute the depth of the pointer and generate a tag of the form 
"p
+// ".
+unsigned PtrDepth = 0;
+do {
+  PtrDepth++;
+  Ty = Ty->getPointeeType().getTypePtr();
+} while (Ty->isPointerType() || Ty->isReferenceType());
+// TODO: Implement C++'s type "similarity" and consider dis-"similar"
+// pointers distinct for non-builtin types.
+if (isa(Ty)) {
+  llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
+  StringRef Name =
+  cast(
+  ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
+  ->getString();
+  SmallString<256> OutName("p");
+  OutName += std::to_string(PtrDepth);
+  OutName += " ";
+  OutName += Name;
+  return createScalarTypeNode(OutName, AnyPtr, Size);
+}
+return AnyPtr;
+  }
 
   // Accesses to arrays are accesses to objects of their element types.
   if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
diff --git a/clang/test/CodeGen/tbaa-pointers.c 
b/clang/test/CodeGen/tbaa-pointers.c
index b9ebe879820012..a3a7aa0d66473e 100644
--- a/clang/test/CodeGen/tbaa-pointers.c
+++ b/clang/test/CodeGen/tbaa-pointers.c
@@ -4,9 +4,9 @@ void p2unsigned(unsigned **ptr) {
   // CHECK-LABEL: define void @p2unsigned(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:  %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0:!.+]]
-  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa 
[[ANY_POINTER_0]]
+  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0:!.+]]
+  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[P2INT_0]]
+  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]]
   // CHECK-NEXT:  ret void
   //
   *ptr = 0;
@@ -16,9 +16,9 @@ void p2unsigned_volatile(unsigned *volatile *ptr) {
   // CHECK-LABEL: define void @p2unsigned_volatile(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[ANY_POINTER_0]]
-  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa 
[[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa 
[[P2INT_0]]
+  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa 
[[P1INT_0]]
   // CHECK-NEXT:   ret void
   //
   *ptr = 0;
@@ -28,10 +28,10 @@ void p3int(int ***ptr) {
   // CHECK-LABEL: define void @p3int(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   

[clang] [analyzer] Add std::any checker (PR #76580)

2023-12-30 Thread via cfe-commits

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


[clang] [clang][modules] Print library module manifest path. (PR #76451)

2023-12-30 Thread Mark de Wever via cfe-commits

mordante wrote:

I had looked at `-print-search-dirs` but it seems buggy. For example, it 
ignores the `-stdlib` flag to the compiler invocation. Solving this seems a lot 
of work. So didn't want to add new features to that code.

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


[clang] [AVR] make the AVR ABI Swift compatible (PR #72298)

2023-12-30 Thread Ben Shi via cfe-commits

benshi001 wrote:

Please refer to my previous commit of AVR ABI, how tests are provided for a 
functional change.

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


[clang] [AVR] make the AVR ABI Swift compatible (PR #72298)

2023-12-30 Thread Ben Shi via cfe-commits

benshi001 wrote:

As I have suggested, any functional change need tests. So I think you need to 
add some tests to show what your changes affect.

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


[clang] bd3d358 - [clang-format][doc] Add the link to POSIX 2.13

2023-12-30 Thread Owen Pan via cfe-commits

Author: Owen Pan
Date: 2023-12-30T01:32:10-08:00
New Revision: bd3d358ec68f686a280ae628f9074fdff1f10fe9

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

LOG: [clang-format][doc] Add the link to POSIX 2.13

Added: 


Modified: 
clang/docs/ClangFormat.rst

Removed: 




diff  --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index 158a14af39732e..8d4017b29fb8ee 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -142,8 +142,9 @@ names. It has the following format:
 * The slash (``/``) is used as the directory separator.
 * A pattern is relative to the directory of the ``.clang-format-ignore`` file
   (or the root directory if the pattern starts with a slash).
-* Patterns follow the rules specified in POSIX 2.13.1, 2.13.2, and Rule 1 of
-  2.13.3.
+* Patterns follow the rules specified in `POSIX 2.13.1, 2.13.2, and Rule 1 of
+  2.13.3 `_.
 * A pattern is negated if it starts with a bang (``!``).
 
 To match all files in a directory, use e.g. ``foo/bar/*``. To match all files 
in



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