[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread Puyan Lotfi via cfe-commits

https://github.com/plotfi updated 
https://github.com/llvm/llvm-project/pull/76608

>From 8c13976e842fcbe3446dff43aaf95a4ae6334ae9 Mon Sep 17 00:00:00 2001
From: Puyan Lotfi 
Date: Fri, 29 Dec 2023 23:13:02 -0800
Subject: [PATCH] [WIP][ObjC] objc_direct method visibility ABI

This patch adds the ability to expose direct ObjC methods as visible
across link boundaries (dylibs). It is done so by using existing
visibility attributes:

```
@interface C
- (void)testMethod:(int)arg1 bar:(float)arg2
  __attribute__((objc_direct))
  __attribute__((visibility("default")));
@end
```

This is a work in progress and there are a few pieces that should be
landed with this within an LLVM release cycle so as not to cause any
inconsistency in the ABI:

  * First, we want some checks that inform the developer when they are
using this feature as part of a framework that this is potentially
brittle. Something similar to the following:
https://github.com/llvm/llvm-project/commit/1b3b69fbda70d

  * Next, we want to move the ObjC method nil checks from the callee
side to something more useful for analysis and optimization that can be
more visible from the caller side. Having the nil checks straight up
in the caller side isn't so great for code size so a good
alternative is to have a thunk between the call site and the callee
for handling nil checks.

  * Finally, any mangling decisions should be finalized before this is
landed.

Much of this has been discussed ahead of time, and there is a more
extensive document on this proposal at:

https://docs.google.com/document/d/16CsNCA2OKWkUM_LCw_qabTcMtPiq9ODVkZHALlDvzR8
---
 clang/include/clang/AST/DeclObjC.h   | 14 
 clang/lib/AST/Mangle.cpp | 10 ++-
 clang/lib/CodeGen/CGObjC.cpp |  4 +-
 clang/lib/CodeGen/CGObjCRuntime.cpp  |  7 +-
 clang/test/CodeGenObjC/objc-direct-wrapper.m | 86 
 5 files changed, 115 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGenObjC/objc-direct-wrapper.m

diff --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index f8f894b4b10d19..4081e5915c0695 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -482,6 +482,20 @@ class ObjCMethodDecl : public NamedDecl, public 
DeclContext {
   /// True if the method is tagged as objc_direct
   bool isDirectMethod() const;
 
+  /// True if method is meant to be visible.
+  ///
+  /// TODO: For now this is only true for a very narrow case where the method
+  /// must be direct and must also be explicitly marked as
+  /// __attribute__((visibility("default"))). In the future it may be possible
+  /// to assume that all direct (or even both direct and indirect) methods are
+  /// visible but for the time being it is prudent to provide this default
+  /// visibility behavior as an opt-in only.
+  bool hasMethodVisibilityDefault() const {
+return isDirectMethod() &&
+   getExplicitVisibility(VisibilityForValue)
+   .value_or(HiddenVisibility) == DefaultVisibility;
+  }
+
   /// True if the method has a parameter that's destroyed in the callee.
   bool hasParamDestroyedInCallee() const;
 
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index d3a6b61fd2bec9..ec409da0e5da00 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -363,10 +363,16 @@ void MangleContext::mangleObjCMethodName(const 
ObjCMethodDecl *MD,
   }
 
   // \01+[ContainerName(CategoryName) SelectorName]
+  // Note: If we are mangling for an objc_direct method with external 
visibility
+  //   then the standard mangling scheme will not work. We must replace the
+  //   square braces with angle braces so in the case of visible direct 
objc
+  //   methods it results in: +
+  //   This will include a prefix _ on Darwin.
   if (includePrefixByte) {
 OS << '\01';
   }
-  OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
+  OS << (MD->isInstanceMethod() ? '-' : '+');
+  OS << (MD->hasMethodVisibilityDefault() ? '<' : '[');
   if (const auto *CID = MD->getCategory()) {
 OS << CID->getClassInterface()->getName();
 if (includeCategoryNamespace) {
@@ -380,7 +386,7 @@ void MangleContext::mangleObjCMethodName(const 
ObjCMethodDecl *MD,
   }
   OS << ' ';
   MD->getSelector().print(OS);
-  OS << ']';
+  OS << (MD->hasMethodVisibilityDefault() ? '>' : ']');
 }
 
 void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index acc85165a470be..3dcd5a8334d102 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -761,7 +761,9 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl 
*OMD,
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
   if (OMD->isDirectMethod()) {
-Fn->setVisibility(llvm::Function::HiddenVisibility);
+Fn->setV

[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff fe2e677aa7aebedd316b1a688db8410855a213c1 
5e69de7ad9b67280db6d62a1c77362d37c343f47 -- clang/include/clang/AST/DeclObjC.h 
clang/lib/AST/Mangle.cpp clang/lib/CodeGen/CGObjC.cpp 
clang/lib/CodeGen/CGObjCRuntime.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 9a12b4007f..4081e5915c 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -492,8 +492,8 @@ public:
   /// visibility behavior as an opt-in only.
   bool hasMethodVisibilityDefault() const {
 return isDirectMethod() &&
-  getExplicitVisibility(VisibilityForValue)
-  .value_or(HiddenVisibility) == DefaultVisibility;
+   getExplicitVisibility(VisibilityForValue)
+   .value_or(HiddenVisibility) == DefaultVisibility;
   }
 
   /// True if the method has a parameter that's destroyed in the callee.
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp 
b/clang/lib/CodeGen/CGObjCRuntime.cpp
index 1841c8ed23..6361f2a786 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -470,9 +470,9 @@ std::string CGObjCRuntime::getSymbolNameForMethod(const 
ObjCMethodDecl *OMD,
   bool includeCategoryName) {
   std::string buffer;
   llvm::raw_string_ostream out(buffer);
-  CGM.getCXXABI().getMangleContext().mangleObjCMethodName(OMD, out,
-   /*includePrefixByte=*/
-   !OMD->hasMethodVisibilityDefault(),
-   includeCategoryName);
+  CGM.getCXXABI().getMangleContext().mangleObjCMethodName(
+  OMD, out,
+  /*includePrefixByte=*/
+  !OMD->hasMethodVisibilityDefault(), includeCategoryName);
   return buffer;
 }

``




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


[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread Puyan Lotfi via cfe-commits

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


[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread Puyan Lotfi via cfe-commits

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


[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Puyan Lotfi (plotfi)


Changes

_**Posting this PR for posterity a bit earlier than I had intended because the 
old Phabricator is crashing 
(https://discourse.llvm.org/t/cant-access-https-reviews-llvm-org/75905):**_

This patch adds the ability to expose direct ObjC methods as visible across 
link boundaries (dylibs). It is done so by using existing visibility attributes:

```
@interface C
- (void)testMethod:(int)arg1 bar:(float)arg2
  __attribute__((objc_direct))
  __attribute__((visibility("default")));
@end
```

This is a work in progress and there are a few pieces that should be landed 
with this within an LLVM release cycle so as not to cause any inconsistency in 
the ABI:

  * First, we want some checks that inform the developer when they are using 
this feature as part of a framework that this is potentially brittle. Something 
similar to the following: 
https://github.com/llvm/llvm-project/commit/1b3b69fbda70d

  * Next, we want to move the ObjC method nil checks from the callee side to 
something more useful for analysis and optimization that can be more visible 
from the caller side. Having the nil checks straight up in the caller side 
isn't so great for code size so a good alternative is to have a thunk between 
the call site and the callee for handling nil checks.

  * Finally, any mangling decisions should be finalized before this is landed.

Much of this has been discussed ahead of time, and there is a more extensive 
document on this proposal at:

https://docs.google.com/document/d/16CsNCA2OKWkUM_LCw_qabTcMtPiq9ODVkZHALlDvzR8

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


5 Files Affected:

- (modified) clang/include/clang/AST/DeclObjC.h (+14) 
- (modified) clang/lib/AST/Mangle.cpp (+8-2) 
- (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1) 
- (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+2-1) 
- (added) clang/test/CodeGenObjC/objc-direct-wrapper.m (+86) 


``diff
diff --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index f8f894b4b10d19..9a12b4007f09f6 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -482,6 +482,20 @@ class ObjCMethodDecl : public NamedDecl, public 
DeclContext {
   /// True if the method is tagged as objc_direct
   bool isDirectMethod() const;
 
+  /// True if method is meant to be visible.
+  ///
+  /// TODO: For now this is only true for a very narrow case where the method
+  /// must be direct and must also be explicitly marked as
+  /// __attribute__((visibility("default"))). In the future it may be possible
+  /// to assume that all direct (or even both direct and indirect) methods are
+  /// visible but for the time being it is prudent to provide this default
+  /// visibility behavior as an opt-in only.
+  bool hasMethodVisibilityDefault() const {
+return isDirectMethod() &&
+  getExplicitVisibility(VisibilityForValue)
+  .value_or(HiddenVisibility) == DefaultVisibility;
+  }
+
   /// True if the method has a parameter that's destroyed in the callee.
   bool hasParamDestroyedInCallee() const;
 
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index d3a6b61fd2bec9..ec409da0e5da00 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -363,10 +363,16 @@ void MangleContext::mangleObjCMethodName(const 
ObjCMethodDecl *MD,
   }
 
   // \01+[ContainerName(CategoryName) SelectorName]
+  // Note: If we are mangling for an objc_direct method with external 
visibility
+  //   then the standard mangling scheme will not work. We must replace the
+  //   square braces with angle braces so in the case of visible direct 
objc
+  //   methods it results in: +
+  //   This will include a prefix _ on Darwin.
   if (includePrefixByte) {
 OS << '\01';
   }
-  OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
+  OS << (MD->isInstanceMethod() ? '-' : '+');
+  OS << (MD->hasMethodVisibilityDefault() ? '<' : '[');
   if (const auto *CID = MD->getCategory()) {
 OS << CID->getClassInterface()->getName();
 if (includeCategoryNamespace) {
@@ -380,7 +386,7 @@ void MangleContext::mangleObjCMethodName(const 
ObjCMethodDecl *MD,
   }
   OS << ' ';
   MD->getSelector().print(OS);
-  OS << ']';
+  OS << (MD->hasMethodVisibilityDefault() ? '>' : ']');
 }
 
 void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index acc85165a470be..3dcd5a8334d102 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -761,7 +761,9 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl 
*OMD,
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
   if (OMD->isDirectMethod()) {
-Fn->setVisibility(llvm::Function::HiddenVisibility);
+Fn->setVisibility(OMD->hasMethodVisibilityDefault()
+  ? ll

[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread Puyan Lotfi via cfe-commits

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


[clang] [WIP][ObjC] objc_direct method visibility ABI (PR #76608)

2023-12-29 Thread Puyan Lotfi via cfe-commits

https://github.com/plotfi created 
https://github.com/llvm/llvm-project/pull/76608

_**Posting this PR for posterity a bit earlier than I had intended because he 
old Phabricator is crashing 
(https://discourse.llvm.org/t/cant-access-https-reviews-llvm-org/75905):**_

This patch adds the ability to expose direct ObjC methods as visible across 
link boundaries (dylibs). It is done so by using existing visibility attributes:

```
@interface C
- (void)testMethod:(int)arg1 bar:(float)arg2
  __attribute__((objc_direct))
  __attribute__((visibility("default")));
@end
```

This is a work in progress and there are a few pieces that should be landed 
with this within an LLVM release cycle so as not to cause any inconsistency in 
the ABI:

  * First, we want some checks that inform the developer when they are using 
this feature as part of a framework that this is potentially brittle. Something 
similar to the following: 
https://github.com/llvm/llvm-project/commit/1b3b69fbda70d

  * Next, we want to move the ObjC method nil checks from the callee side to 
something more useful for analysis and optimization that can be more visible 
from the caller side. Having the nil checks straight up in the caller side 
isn't so great for code size so a good alternative is to have a thunk between 
the call site and the callee for handling nil checks.

  * Finally, any mangling decisions should be finalized before this is landed.

Much of this has been discussed ahead of time, and there is a more extensive 
document on this proposal at:

https://docs.google.com/document/d/16CsNCA2OKWkUM_LCw_qabTcMtPiq9ODVkZHALlDvzR8

>From 5e69de7ad9b67280db6d62a1c77362d37c343f47 Mon Sep 17 00:00:00 2001
From: Puyan Lotfi 
Date: Fri, 29 Dec 2023 23:13:02 -0800
Subject: [PATCH] [WIP][ObjC] objc_direct method visibility ABI

This patch adds the ability to expose direct ObjC methods as visible
across link boundaries (dylibs). It is done so by using existing
visibility attributes:

```
@interface C
- (void)testMethod:(int)arg1 bar:(float)arg2
  __attribute__((objc_direct))
  __attribute__((visibility("default")));
@end
```

This is a work in progress and there are a few pieces that should be
landed with this within an LLVM release cycle so as not to cause any
inconsistency in the ABI:

  * First, we want some checks that inform the developer when they are
using this feature as part of a framework that this is potentially
brittle. Something similar to the following:
https://github.com/llvm/llvm-project/commit/1b3b69fbda70d

  * Next, we want to move the ObjC method nil checks from the callee
side to something more useful for analysis and optimization that can be
more visible from the caller side. Having the nil checks straight up
in the caller side isn't so great for code size so a good
alternative is to have a thunk between the call site and the callee
for handling nil checks.

  * Finally, any mangling decisions should be finalized before this is
landed.

Much of this has been discussed ahead of time, and there is a more
extensive document on this proposal at:

https://docs.google.com/document/d/16CsNCA2OKWkUM_LCw_qabTcMtPiq9ODVkZHALlDvzR8
---
 clang/include/clang/AST/DeclObjC.h   | 14 
 clang/lib/AST/Mangle.cpp | 10 ++-
 clang/lib/CodeGen/CGObjC.cpp |  4 +-
 clang/lib/CodeGen/CGObjCRuntime.cpp  |  3 +-
 clang/test/CodeGenObjC/objc-direct-wrapper.m | 86 
 5 files changed, 113 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenObjC/objc-direct-wrapper.m

diff --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index f8f894b4b10d19..9a12b4007f09f6 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -482,6 +482,20 @@ class ObjCMethodDecl : public NamedDecl, public 
DeclContext {
   /// True if the method is tagged as objc_direct
   bool isDirectMethod() const;
 
+  /// True if method is meant to be visible.
+  ///
+  /// TODO: For now this is only true for a very narrow case where the method
+  /// must be direct and must also be explicitly marked as
+  /// __attribute__((visibility("default"))). In the future it may be possible
+  /// to assume that all direct (or even both direct and indirect) methods are
+  /// visible but for the time being it is prudent to provide this default
+  /// visibility behavior as an opt-in only.
+  bool hasMethodVisibilityDefault() const {
+return isDirectMethod() &&
+  getExplicitVisibility(VisibilityForValue)
+  .value_or(HiddenVisibility) == DefaultVisibility;
+  }
+
   /// True if the method has a parameter that's destroyed in the callee.
   bool hasParamDestroyedInCallee() const;
 
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index d3a6b61fd2bec9..ec409da0e5da00 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -363,10 +363,16 @@ void MangleContext::mangleObjCMethodNa

[clang] [llvm] [RISCV] Add MC layer support for Zicfiss. (PR #66043)

2023-12-29 Thread Yeting Kuo via cfe-commits

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


[clang] 3dc0638 - [RISCV] Add MC layer support for Zicfiss. (#66043)

2023-12-29 Thread via cfe-commits

Author: Yeting Kuo
Date: 2023-12-30T15:40:20+08:00
New Revision: 3dc0638cfc19e140daff7bf1281648daca8212fa

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

LOG: [RISCV] Add MC layer support for Zicfiss. (#66043)

The patch adds the instructions in Zicfiss extension. Zicfiss extension
is to support shadow stack for control flow integrity. This patch is
based on version [0.3.1].

[0.3.1]: https://github.com/riscv/riscv-cfi/releases/tag/v0.3.1

Added: 
llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td
llvm/test/MC/RISCV/compressed-zicfiss.s
llvm/test/MC/RISCV/rv32zicfiss-invalid.s
llvm/test/MC/RISCV/rv64zicfiss-invalid.s
llvm/test/MC/RISCV/zicfiss-valid.s

Modified: 
clang/test/Preprocessor/riscv-target-features.c
llvm/docs/RISCVUsage.rst
llvm/lib/Support/RISCVISAInfo.cpp
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
llvm/lib/Target/RISCV/RISCVRegisterInfo.td
llvm/test/MC/RISCV/attribute-arch.s
llvm/unittests/Support/RISCVISAInfoTest.cpp

Removed: 




diff  --git a/clang/test/Preprocessor/riscv-target-features.c 
b/clang/test/Preprocessor/riscv-target-features.c
index b16a1b0c17300a..02d8d34116f804 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -118,6 +118,7 @@
 // CHECK-NOT: __riscv_zfa {{.*$}}
 // CHECK-NOT: __riscv_zfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zicfilp {{.*$}}
+// CHECK-NOT: __riscv_zicfiss {{.*$}}
 // CHECK-NOT: __riscv_zicond {{.*$}}
 // CHECK-NOT: __riscv_zimop {{.*$}}
 // CHECK-NOT: __riscv_zcmop {{.*$}}
@@ -1287,3 +1288,11 @@
 // RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -E -dM %s \
 // RUN:   -munaligned-access -o - | FileCheck %s 
--check-prefix=CHECK-MISALIGNED-FAST
 // CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1
+
+// RUN: %clang -target riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32izicfiss0p4 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s
+// RUN: %clang -target riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64izicfiss0p4 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s
+// CHECK-ZICFISS-EXT: __riscv_zicfiss 4000{{$}}

diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 4dc04bc8361e67..99c7146825f5ee 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -212,7 +212,7 @@ The primary goal of experimental support is to assist in 
the process of ratifica
 ``experimental-zfbfmin``, ``experimental-zvfbfmin``, ``experimental-zvfbfwma``
   LLVM implements assembler support for the `0.8.0 draft specification 
`_.
 
-``experimental-zicfilp``
+``experimental-zicfilp``, ``experimental-zicfiss``
   LLVM implements the `0.4 draft specification 
`__.
 
 ``experimental-zicond``

diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp 
b/llvm/lib/Support/RISCVISAInfo.cpp
index 467494da4db168..a9b7e209915a13 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -195,6 +195,8 @@ static const RISCVSupportedExtension 
SupportedExperimentalExtensions[] = {
 {"zfbfmin", RISCVExtensionVersion{0, 8}},
 
 {"zicfilp", RISCVExtensionVersion{0, 4}},
+{"zicfiss", RISCVExtensionVersion{0, 4}},
+
 {"zicond", RISCVExtensionVersion{1, 0}},
 
 {"zimop", RISCVExtensionVersion{0, 1}},
@@ -1021,6 +1023,7 @@ static const char *ImpliedExtsZfinx[] = {"zicsr"};
 static const char *ImpliedExtsZhinx[] = {"zhinxmin"};
 static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
 static const char *ImpliedExtsZicntr[] = {"zicsr"};
+static const char *ImpliedExtsZicfiss[] = {"zicsr", "zimop"};
 static const char *ImpliedExtsZihpm[] = {"zicsr"};
 static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"};
 static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zbkx",
@@ -1093,6 +1096,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
 {{"zfinx"}, {ImpliedExtsZfinx}},
 {{"zhinx"}, {ImpliedExtsZhinx}},
 {{"zhinxmin"}, {ImpliedExtsZhinxmin}},
+{{"zicfiss"}, {ImpliedExtsZicfiss}},
 {{"zicntr"}, {ImpliedExtsZicntr}},
 {{"zihpm"}, {ImpliedExtsZihpm}},
 {{"zk"}, {ImpliedExtsZk}},

diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index a639634d36a125..ed80da14c79574 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassemble

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

2023-12-29 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


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

2023-12-29 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] fe2e677 - [clang-format][doc] Add .clang-format-ignore to the release notes

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

Author: Owen Pan
Date: 2023-12-29T23:12:16-08:00
New Revision: fe2e677aa7aebedd316b1a688db8410855a213c1

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

LOG: [clang-format][doc] Add .clang-format-ignore to the release notes

Added: 


Modified: 
clang/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d5391702385a7..0c8fec691bf3c9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1041,6 +1041,7 @@ clang-format
 - Add ``BreakAdjacentStringLiterals`` option.
 - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property
   attributes (like ``nonatomic, strong, nullable``).
+- Add ``.clang-format-ignore`` files.
 
 libclang
 



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


[clang] 3507959 - [clang-format][doc] Fix format errors.

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

Author: Owen Pan
Date: 2023-12-29T22:52:07-08:00
New Revision: 3507959e441ed9470818e7c6ef16d9bbcfe6a999

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

LOG: [clang-format][doc] Fix format errors.

Added: 


Modified: 
clang/docs/ClangFormat.rst

Removed: 




diff  --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index 67fdffbd116d8a..158a14af39732e 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -134,16 +134,17 @@ Available style options are described in 
:doc:`ClangFormatStyleOptions`.
 You can create ``.clang-format-ignore`` files to make ``clang-format`` ignore
 certain files. A ``.clang-format-ignore`` file consists of patterns of file 
path
 names. It has the following format:
-- A blank line is skipped.
-- Leading and trailing spaces of a line are trimmed.
-- A line starting with a hash (``#``) is a comment.
-- A non-comment line is a single pattern.
-- 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.
-- A pattern is negated if it starts with a bang (``!``).
+
+* A blank line is skipped.
+* Leading and trailing spaces of a line are trimmed.
+* A line starting with a hash (``#``) is a comment.
+* A non-comment line is a single pattern.
+* 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.
+* 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
 the directory of the ``.clang-format-ignore`` file, use ``*``.



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


[clang] [clang][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker (PR #76557)

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

benshi001 wrote:

Thanks for your help. Happy new year!

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


[clang] [clang][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker (PR #76557)

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

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


[clang] 925ff9e - [clang][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker (#76557)

2023-12-29 Thread via cfe-commits

Author: Ben Shi
Date: 2023-12-30T14:49:42+08:00
New Revision: 925ff9e1a218720cd61bd7c9f5f85ded4ecbf9a1

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

LOG: [clang][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker 
(#76557)

Co-authored-by: Balazs Benics 

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/test/Analysis/stream-errno.c

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3c08d1808b0e7f..2d5391702385a7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1126,9 +1126,11 @@ Improvements
 
 
 - Improved the ``unix.StdCLibraryFunctions`` checker by modeling more
-  functions like ``send``, ``recv``, ``readlink`` and ``errno`` behavior.
+  functions like ``send``, ``recv``, ``readlink``, ``fflush`` and
+  ``errno`` behavior.
   (`52ac71f92d38 
`_,
   `#71373 `_,
+  `#76557 `_,
   `#71392 `_)
 
 - Fixed a false negative for when accessing a nonnull property (ObjC).

diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index fffcaf7ed18fb7..4ca49b9c0546d9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2244,6 +2244,14 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
 .ArgConstraint(NotNull(ArgNo(0)))
 .ArgConstraint(NotNull(ArgNo(1;
 
+// int fflush(FILE *stream);
+addToFunctionSummaryMap(
+"fflush", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
+Summary(NoEvalCall)
+.Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
+.Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
+  ErrnoNEZeroIrrelevant, GenericFailureMsg));
+
 // long ftell(FILE *stream);
 // From 'The Open Group Base Specifications Issue 7, 2018 edition':
 // "The ftell() function shall not change the setting of errno if

diff  --git a/clang/test/Analysis/stream-errno.c 
b/clang/test/Analysis/stream-errno.c
index bf0a61db2424f9..f44ee6070708b2 100644
--- a/clang/test/Analysis/stream-errno.c
+++ b/clang/test/Analysis/stream-errno.c
@@ -222,3 +222,29 @@ void check_fileno(void) {
   }
   if (errno) {} // expected-warning{{An undefined value may be read from 
'errno'}}
 }
+
+void check_fflush_opened_file(void) {
+  FILE *F = tmpfile();
+  if (!F)
+return;
+  int N = fflush(F);
+  if (N == EOF) {
+clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+if (errno) {}// no-warning
+  } else {
+clang_analyzer_eval(N == 0); // expected-warning{{TRUE}}
+if (errno) {}// expected-warning{{An undefined value 
may be read from 'errno'}}
+  }
+  fclose(F);
+}
+
+void check_fflush_all(void) {
+  int N = fflush(NULL);
+  if (N == 0) {
+if (errno) {}// expected-warning{{An undefined value 
may be read from 'errno'}}
+  } else {
+clang_analyzer_eval(N == EOF);   // expected-warning{{TRUE}}
+clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+if (errno) {}// no-warning
+  }
+}



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


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

2023-12-29 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 886655869cef2e0f11da8981da30d70ad7892ff9 
4d3ff8bd92f92404db1d1dd56e8ff4a5b5226dbb -- 
libcxx/test/std/utilities/variant/variant.visit/member.visit.pass.cpp 
libcxx/test/std/utilities/variant/variant.visit/member.visit.robust_against_adl.pass.cpp
 
libcxx/test/std/utilities/variant/variant.visit/member.visit_return_type.pass.cpp
 libcxx/include/variant 
libcxx/test/std/utilities/variant/variant.visit/visit.return_type.pass.cpp 
libcxx/test/std/utilities/variant/variant.visit/visit.robust_against_adl.pass.cpp
``





View the diff from clang-format here.


``diff
diff --git 
a/libcxx/test/std/utilities/variant/variant.visit/visit.return_type.pass.cpp 
b/libcxx/test/std/utilities/variant/variant.visit/visit.return_type.pass.cpp
index eb425c07f9..246b01a68f 100644
--- a/libcxx/test/std/utilities/variant/variant.visit/visit.return_type.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit/visit.return_type.pass.cpp
@@ -26,7 +26,7 @@ template 
 void test_call_operator_forwarding() {
   using Fn = ForwardingCallObject;
   Fn obj{};
-  const Fn &cobj = obj;
+  const Fn& cobj = obj;
   { // test call operator forwarding - no variant
 std::visit(obj);
 assert(Fn::check_call<>(CT_NonConst | CT_LValue));
@@ -41,63 +41,63 @@ void test_call_operator_forwarding() {
 using V = std::variant;
 V v(42);
 std::visit(obj, v);
-assert(Fn::check_call(CT_NonConst | CT_LValue));
+assert(Fn::check_call(CT_NonConst | CT_LValue));
 std::visit(cobj, v);
-assert(Fn::check_call(CT_Const | CT_LValue));
+assert(Fn::check_call(CT_Const | CT_LValue));
 std::visit(std::move(obj), v);
-assert(Fn::check_call(CT_NonConst | CT_RValue));
+assert(Fn::check_call(CT_NonConst | CT_RValue));
 std::visit(std::move(cobj), v);
-assert(Fn::check_call(CT_Const | CT_RValue));
+assert(Fn::check_call(CT_Const | CT_RValue));
   }
   { // test call operator forwarding - single variant, multi arg
 using V = std::variant;
 V v(42l);
 std::visit(obj, v);
-assert(Fn::check_call(CT_NonConst | CT_LValue));
+assert(Fn::check_call(CT_NonConst | CT_LValue));
 std::visit(cobj, v);
-assert(Fn::check_call(CT_Const | CT_LValue));
+assert(Fn::check_call(CT_Const | CT_LValue));
 std::visit(std::move(obj), v);
-assert(Fn::check_call(CT_NonConst | CT_RValue));
+assert(Fn::check_call(CT_NonConst | CT_RValue));
 std::visit(std::move(cobj), v);
-assert(Fn::check_call(CT_Const | CT_RValue));
+assert(Fn::check_call(CT_Const | CT_RValue));
   }
   { // test call operator forwarding - multi variant, multi arg
-using V = std::variant;
-using V2 = std::variant;
+using V  = std::variant;
+using V2 = std::variant;
 V v(42l);
 V2 v2("hello");
 std::visit(obj, v, v2);
-assert((Fn::check_call(CT_NonConst | CT_LValue)));
+assert((Fn::check_call(CT_NonConst | CT_LValue)));
 std::visit(cobj, v, v2);
-assert((Fn::check_call(CT_Const | CT_LValue)));
+assert((Fn::check_call(CT_Const | CT_LValue)));
 std::visit(std::move(obj), v, v2);
-assert((Fn::check_call(CT_NonConst | CT_RValue)));
+assert((Fn::check_call(CT_NonConst | CT_RValue)));
 std::visit(std::move(cobj), v, v2);
-assert((Fn::check_call(CT_Const | CT_RValue)));
+assert((Fn::check_call(CT_Const | CT_RValue)));
   }
   {
 using V = std::variant;
 V v1(42l), v2("hello"), v3(101), v4(1.1);
 std::visit(obj, v1, v2, v3, v4);
-assert((Fn::check_call(CT_NonConst 
| CT_LValue)));
+assert((Fn::check_call(CT_NonConst | 
CT_LValue)));
 std::visit(cobj, v1, v2, v3, v4);
-assert((Fn::check_call(CT_Const | 
CT_LValue)));
+assert((Fn::check_call(CT_Const | 
CT_LValue)));
 std::visit(std::move(obj), v1, v2, v3, v4);
-assert((Fn::check_call(CT_NonConst 
| CT_RValue)));
+assert((Fn::check_call(CT_NonConst | 
CT_RValue)));
 std::visit(std::move(cobj), v1, v2, v3, v4);
-assert((Fn::check_call(CT_Const | 
CT_RValue)));
+assert((Fn::check_call(CT_Const | 
CT_RValue)));
   }
   {
 using V = std::variant;
 V v1(42l), v2("hello"), v3(nullptr), v4(1.1);
 std::visit(obj, v1, v2, v3, v4);
-assert((Fn::check_call(CT_NonConst | CT_LValue)));
+assert((Fn::check_call(CT_NonConst | 
CT_LValue)));
 std::visit(cobj, v1, v2, v3, v4);
-assert((Fn::check_call(CT_Const | 
CT_LValue)));
+assert((Fn::check_call(CT_Const | 
CT_LValue)));
 std::visit(std::move(obj), v1, v2, v3, v4);
-assert((Fn::check_call(CT_NonConst | CT_RValue)));
+assert((Fn::check_call(CT_NonConst | 
CT_RValue)));
 std::visit(std::move(cobj), v1, v2, v3, v4);
-assert((Fn::check_call(CT_Const | 
CT_RValue)));
+assert((Fn::check_call(CT_Const | 
CT_RValue)));
   }
 }
 
@@ -109,69

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

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

https://github.com/MaxEW707 updated 
https://github.com/llvm/llvm-project/pull/76596

>From ff2c4b9310950c56a4e2a2b7752f3c3c442a6805 Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Fri, 29 Dec 2023 04:02:10 -0500
Subject: [PATCH 1/3] Add `clang::behaves_like_std(...)` attribute

---
 clang/include/clang/Basic/Attr.td |  9 +++
 clang/include/clang/Basic/AttrDocs.td | 29 
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/Sema/SemaDecl.cpp   | 47 +---
 clang/lib/Sema/SemaDeclAttr.cpp   | 16 +
 clang/lib/Sema/SemaExpr.cpp   | 21 ++
 clang/test/CodeGenCXX/builtin-std-move.cpp| 72 +++
 clang/test/CodeGenCXX/builtins.cpp|  7 ++
 .../SemaCXX/err-invalid-behaves-like-std.cpp  | 20 ++
 .../SemaCXX/unqualified-std-call-fixits.cpp   | 28 +++-
 clang/test/SemaCXX/warn-pessmizing-move.cpp   | 22 ++
 clang/test/SemaCXX/warn-redundant-move.cpp| 47 ++--
 clang/test/SemaCXX/warn-self-move.cpp | 55 ++
 13 files changed, 359 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/SemaCXX/err-invalid-behaves-like-std.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17d..5ad72c7026425d 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1922,6 +1922,15 @@ def Convergent : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def BehavesLikeStd : InheritableAttr {
+  let Spellings = [Clang<"behaves_like_std">];
+  let Subjects = SubjectList<[Function]>;
+  let Args = [StringArgument<"StdFunction">];
+  let LangOpts = [CPlusPlus];
+  let PragmaAttributeSupport = 0;
+  let Documentation = [BehavesLikeStdDocs];
+}
+
 def NoInline : DeclOrStmtAttr {
   let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">,
CXX11<"clang", "noinline">, C23<"clang", "noinline">,
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 98a7ecc7fd7df3..5d99bb87587ceb 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -577,6 +577,35 @@ effect applies only to a specific function pointer. For 
example:
   }];
 }
 
+def BehavesLikeStdDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+This function attribute can be used to tag functions that behave like `std` 
functions.
+This allows custom STL libraries in non-freestanding environments to get the 
same benefits
+as the `std` functions that are treated like builtins without conflicting with 
the `std` declarations
+and without including costly `std` headers.
+
+This attribute currently supports all `std` functions that are implicitly 
treated as builtins which include
+`std::addressof`, `std::forward`, `std::forward_like`, `std::move`, 
`std::move_if_noexcept`, and `std::as_const`.
+
+.. code-block:: c
+
+  namespace MySTL {
+template
+[[clang::behaves_like_std("move")]] constexpr remove_reference_t&& 
move(T &&t) noexcept;
+  }
+
+  template
+  [[clang::behaves_like_std("move")]] constexpr remove_reference_t&& 
myMove(T &&t) noexcept;
+
+  void example(std::string a, std::string b) {
+foo(MySTL::move(a));
+foo(myMove(b));
+  }
+
+  }];
+}
+
 def NoInlineDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aebb7d9b945c33..4ebcda089ca307 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3132,6 +3132,8 @@ def err_attribute_no_member_function : Error<
 def err_attribute_parameter_types : Error<
   "%0 attribute parameter types do not match: parameter %1 of function %2 has 
type %3, "
   "but parameter %4 of function %5 has type %6">;
+def err_attribute_invalid_std_builtin : Error<
+  "not a valid std builtin for attribute %0">;
 
 def err_attribute_too_many_arguments : Error<
   "%0 attribute takes no more than %1 argument%s1">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ffbe317d559995..2498af5c7e6a1a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9753,14 +9753,11 @@ static Scope *getTagInjectionScope(Scope *S, const 
LangOptions &LangOpts) {
   return S;
 }
 
-/// Determine whether a declaration matches a known function in namespace std.
-static bool isStdBuiltin(ASTContext &Ctx, FunctionDecl *FD,
- unsigned BuiltinID) {
+/// Determine whether a declaration matches a known cast function in namespace
+/// std.
+static bool isStdCastBuiltin(ASTContext &Ctx, FunctionDecl *FD,
+ unsigned BuiltinID) {
   switch (BuiltinID) {
-  case Builtin::BI__GetExceptionInfo:
-// No type checking whatsoever.
-return Ctx.g

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

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

https://github.com/MaxEW707 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-29 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 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] ca8441d - [clang-format][NFC] Fix a typo.

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

Author: Owen Pan
Date: 2023-12-29T19:47:08-08:00
New Revision: ca8441d6dbd36003288ef412295e7b946a8bb893

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

LOG: [clang-format][NFC] Fix a typo.

Added: 


Modified: 
clang/lib/Format/MatchFilePath.cpp

Removed: 




diff  --git a/clang/lib/Format/MatchFilePath.cpp 
b/clang/lib/Format/MatchFilePath.cpp
index 412ee4954587e0..062b334dcdd8fd 100644
--- a/clang/lib/Format/MatchFilePath.cpp
+++ b/clang/lib/Format/MatchFilePath.cpp
@@ -19,8 +19,8 @@ using namespace llvm;
 namespace clang {
 namespace format {
 
-// Check whether `FilePath` matches `Pattern` based on POSIX (1003.1-2008)
-// 2.13.1, 2.13.2, and Rule 1 of 2.13.3.
+// Check whether `FilePath` matches `Pattern` based on POSIX 2.13.1, 2.13.2, 
and
+// Rule 1 of 2.13.3.
 bool matchFilePath(StringRef Pattern, StringRef FilePath) {
   assert(!Pattern.empty());
   assert(!FilePath.empty());



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


[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

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

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


[clang] 0930812 - [clang-format] Add .clang-format-ignore for ignoring files (#76327)

2023-12-29 Thread via cfe-commits

Author: Owen Pan
Date: 2023-12-29T19:40:44-08:00
New Revision: 09308122c6c0fa9eb3d729a2b2909733cbbc2160

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

LOG: [clang-format] Add .clang-format-ignore for ignoring files (#76327)

Closes #52975.

Added: 
clang/test/Format/clang-format-ignore.cpp

Modified: 
clang/docs/ClangFormat.rst
clang/tools/clang-format/ClangFormat.cpp

Removed: 




diff  --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index f52f35550d03eb..67fdffbd116d8a 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -131,6 +131,25 @@ An easy way to create the ``.clang-format`` file is:
 
 Available style options are described in :doc:`ClangFormatStyleOptions`.
 
+You can create ``.clang-format-ignore`` files to make ``clang-format`` ignore
+certain files. A ``.clang-format-ignore`` file consists of patterns of file 
path
+names. It has the following format:
+- A blank line is skipped.
+- Leading and trailing spaces of a line are trimmed.
+- A line starting with a hash (``#``) is a comment.
+- A non-comment line is a single pattern.
+- 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.
+- 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
+the directory of the ``.clang-format-ignore`` file, use ``*``.
+Multiple ``.clang-format-ignore`` files are supported similar to the
+``.clang-format`` files, with a lower directory level file voiding the higher
+level ones.
 
 Vim Integration
 ===

diff  --git a/clang/test/Format/clang-format-ignore.cpp 
b/clang/test/Format/clang-format-ignore.cpp
new file mode 100644
index 00..0d6396a64a668d
--- /dev/null
+++ b/clang/test/Format/clang-format-ignore.cpp
@@ -0,0 +1,33 @@
+// RUN: rm -rf %t.dir
+// RUN: mkdir -p %t.dir/level1/level2
+
+// RUN: cd %t.dir
+// RUN: echo "*" > .clang-format-ignore
+// RUN: echo "level*/*.c*" >> .clang-format-ignore
+// RUN: echo "*/*2/foo.*" >> .clang-format-ignore
+// RUN: touch foo.cc
+// RUN: clang-format -verbose .clang-format-ignore foo.cc 2> %t.stderr
+// RUN: not grep Formatting %t.stderr
+
+// RUN: cd level1
+// RUN: touch bar.cc baz.c
+// RUN: clang-format -verbose bar.cc baz.c 2> %t.stderr
+// RUN: not grep Formatting %t.stderr
+
+// RUN: cd level2
+// RUN: touch foo.c foo.js
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: not grep Formatting %t.stderr
+
+// RUN: touch .clang-format-ignore
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: grep "Formatting \[1/2] foo.c" %t.stderr
+// RUN: grep "Formatting \[2/2] foo.js" %t.stderr
+
+// RUN: echo "*.js" > .clang-format-ignore
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: grep "Formatting \[1/2] foo.c" %t.stderr
+// RUN: not grep "Formatting \[2/2] foo.js" %t.stderr
+
+// RUN: cd ../../..
+// RUN: rm -rf %t.dir

diff  --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index d2e3d8d43aef21..be34dbbe886a15 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -12,6 +12,7 @@
 ///
 
//===--===//
 
+#include "../../lib/Format/MatchFilePath.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -570,6 +571,69 @@ static int dumpConfig(bool IsSTDIN) {
   return 0;
 }
 
+// Check whether `FilePath` is ignored according to the nearest
+// .clang-format-ignore file based on the rules below:
+// - A blank line is skipped.
+// - Leading and trailing spaces of a line are trimmed.
+// - A line starting with a hash (`#`) is a comment.
+// - A non-comment line is a single pattern.
+// - 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).
+// - A pattern is negated if it starts with a bang (`!`).
+static bool isIgnored(StringRef FilePath) {
+  using namespace llvm::sys::fs;
+  if (!is_regular_file(FilePath))
+return false;
+
+  using namespace llvm::sys::path;
+  SmallString<128> Path, AbsPath{FilePath};
+
+  make_absolute(AbsPath);
+  remove_dots(AbsPath, /*remove_dot_dot=*/true);
+
+  StringRef IgnoreDir{AbsPath};
+  do {
+IgnoreDir = parent_path(IgnoreDir);
+if (IgnoreDir.empty())
+  return false;
+
+Path = IgnoreDir;
+append(Path, ".clang

[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

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

https://github.com/owenca updated 
https://github.com/llvm/llvm-project/pull/76327

>From 4afd12db61528b40d842a7fbee9af37c2235822c Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Sun, 24 Dec 2023 01:18:55 -0800
Subject: [PATCH 1/9] [clang-format] Add .clang-format.ignore for ignoring
 files

Closes #52975.
---
 clang/docs/ClangFormat.rst| 18 ++
 clang/test/Format/clang-format-ignore.cpp | 24 
 clang/tools/clang-format/ClangFormat.cpp  | 71 ++-
 3 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Format/clang-format-ignore.cpp

diff --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index f52f35550d03eb..a0b28f2273991f 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -131,6 +131,24 @@ An easy way to create the ``.clang-format`` file is:
 
 Available style options are described in :doc:`ClangFormatStyleOptions`.
 
+You can create ``.clang-format-ignore`` files to make ``clang-format`` ignore
+certain files. A ``.clang-format-ignore`` file consists of patterns of file 
path
+names. It has the following format:
+- A blank line is skipped.
+- Leading and trailing spaces of a line are trimmed.
+- A line starting with a hash (``#``) is a comment.
+- A non-comment line is a single pattern.
+- 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.
+- 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
+the directory of the ``.clang-format-ignore`` file, use ``*``.
+Multiple ``.clang-format-ignore`` files are supported similar to the
+``.clang-format`` files, with a lower directory level file voiding the higher
+level ones.
 
 Vim Integration
 ===
diff --git a/clang/test/Format/clang-format-ignore.cpp 
b/clang/test/Format/clang-format-ignore.cpp
new file mode 100644
index 00..a2210266034d4c
--- /dev/null
+++ b/clang/test/Format/clang-format-ignore.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t.dir/level1/level2
+
+// RUN: cd %t.dir
+// RUN: printf "*\nlevel*/*.c*\n*/*2/foo.*\n" > .clang-format-ignore
+// RUN: touch foo.cc
+// RUN: clang-format -verbose .clang-format-ignore foo.cc 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+// RUN: cd level1
+// RUN: touch bar.cc baz.c
+// RUN: clang-format -verbose bar.cc baz.c 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+// RUN: cd level2
+// RUN: touch foo.c foo.js
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+// RUN: printf "*.js\n" > .clang-format-ignore
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: grep -E "Formatting (.*)foo.c(.*)" %t.stderr
+// RUN: not grep -E "Formatting (.*)foo.js(.*)" %t.stderr
+
+// RUN: cd ../../..
+// RUN: rm -rf %t.dir
diff --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index d2e3d8d43aef21..be78f8cbebf5e1 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -12,6 +12,7 @@
 ///
 
//===--===//
 
+#include "../../lib/Format/MatchFilePath.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -570,6 +571,71 @@ static int dumpConfig(bool IsSTDIN) {
   return 0;
 }
 
+// Check whether `FilePath` is ignored according to the nearest
+// .clang-format-ignore file based on the rules below:
+// - A blank line is skipped.
+// - Leading and trailing spaces of a line are trimmed.
+// - A line starting with a hash (`#`) is a comment.
+// - A non-comment line is a single pattern.
+// - 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).
+// - A pattern is negated if it starts with a bang (`!`).
+static bool isIgnored(const StringRef FilePath) {
+  if (!llvm::sys::fs::is_regular_file(FilePath))
+return false;
+
+  using namespace llvm::sys::path;
+  SmallString<128> Path, AbsPath{convert_to_slash(FilePath)};
+
+  llvm::vfs::getRealFileSystem()->makeAbsolute(AbsPath);
+  remove_dots(AbsPath, /*remove_dot_dot=*/true);
+
+  StringRef IgnoreDir{AbsPath};
+  do {
+IgnoreDir = parent_path(IgnoreDir);
+if (IgnoreDir.empty())
+  return false;
+
+Path = IgnoreDir;
+append(Path, ".clang-format-ignore");
+  } while (!llvm::sys::fs::is_regular_file(Path));
+
+  std::ifstream IgnoreFile{Path.c_str()};
+  if (!IgnoreFile.good())
+return false;
+
+  bool HasMatch = false;
+  for (std::string Pattern; std::getline(IgnoreFile, Pattern);) {
+   

[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

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

https://github.com/owenca updated 
https://github.com/llvm/llvm-project/pull/76327

>From 4afd12db61528b40d842a7fbee9af37c2235822c Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Sun, 24 Dec 2023 01:18:55 -0800
Subject: [PATCH 1/8] [clang-format] Add .clang-format.ignore for ignoring
 files

Closes #52975.
---
 clang/docs/ClangFormat.rst| 18 ++
 clang/test/Format/clang-format-ignore.cpp | 24 
 clang/tools/clang-format/ClangFormat.cpp  | 71 ++-
 3 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Format/clang-format-ignore.cpp

diff --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index f52f35550d03eb..a0b28f2273991f 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -131,6 +131,24 @@ An easy way to create the ``.clang-format`` file is:
 
 Available style options are described in :doc:`ClangFormatStyleOptions`.
 
+You can create ``.clang-format-ignore`` files to make ``clang-format`` ignore
+certain files. A ``.clang-format-ignore`` file consists of patterns of file 
path
+names. It has the following format:
+- A blank line is skipped.
+- Leading and trailing spaces of a line are trimmed.
+- A line starting with a hash (``#``) is a comment.
+- A non-comment line is a single pattern.
+- 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.
+- 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
+the directory of the ``.clang-format-ignore`` file, use ``*``.
+Multiple ``.clang-format-ignore`` files are supported similar to the
+``.clang-format`` files, with a lower directory level file voiding the higher
+level ones.
 
 Vim Integration
 ===
diff --git a/clang/test/Format/clang-format-ignore.cpp 
b/clang/test/Format/clang-format-ignore.cpp
new file mode 100644
index 00..a2210266034d4c
--- /dev/null
+++ b/clang/test/Format/clang-format-ignore.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t.dir/level1/level2
+
+// RUN: cd %t.dir
+// RUN: printf "*\nlevel*/*.c*\n*/*2/foo.*\n" > .clang-format-ignore
+// RUN: touch foo.cc
+// RUN: clang-format -verbose .clang-format-ignore foo.cc 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+// RUN: cd level1
+// RUN: touch bar.cc baz.c
+// RUN: clang-format -verbose bar.cc baz.c 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+// RUN: cd level2
+// RUN: touch foo.c foo.js
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+// RUN: printf "*.js\n" > .clang-format-ignore
+// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr
+// RUN: grep -E "Formatting (.*)foo.c(.*)" %t.stderr
+// RUN: not grep -E "Formatting (.*)foo.js(.*)" %t.stderr
+
+// RUN: cd ../../..
+// RUN: rm -rf %t.dir
diff --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index d2e3d8d43aef21..be78f8cbebf5e1 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -12,6 +12,7 @@
 ///
 
//===--===//
 
+#include "../../lib/Format/MatchFilePath.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -570,6 +571,71 @@ static int dumpConfig(bool IsSTDIN) {
   return 0;
 }
 
+// Check whether `FilePath` is ignored according to the nearest
+// .clang-format-ignore file based on the rules below:
+// - A blank line is skipped.
+// - Leading and trailing spaces of a line are trimmed.
+// - A line starting with a hash (`#`) is a comment.
+// - A non-comment line is a single pattern.
+// - 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).
+// - A pattern is negated if it starts with a bang (`!`).
+static bool isIgnored(const StringRef FilePath) {
+  if (!llvm::sys::fs::is_regular_file(FilePath))
+return false;
+
+  using namespace llvm::sys::path;
+  SmallString<128> Path, AbsPath{convert_to_slash(FilePath)};
+
+  llvm::vfs::getRealFileSystem()->makeAbsolute(AbsPath);
+  remove_dots(AbsPath, /*remove_dot_dot=*/true);
+
+  StringRef IgnoreDir{AbsPath};
+  do {
+IgnoreDir = parent_path(IgnoreDir);
+if (IgnoreDir.empty())
+  return false;
+
+Path = IgnoreDir;
+append(Path, ".clang-format-ignore");
+  } while (!llvm::sys::fs::is_regular_file(Path));
+
+  std::ifstream IgnoreFile{Path.c_str()};
+  if (!IgnoreFile.good())
+return false;
+
+  bool HasMatch = false;
+  for (std::string Pattern; std::getline(IgnoreFile, Pattern);) {
+   

[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

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


@@ -570,6 +571,70 @@ static int dumpConfig(bool IsSTDIN) {
   return 0;
 }
 
+// Check whether `FilePath` is ignored according to the nearest
+// .clang-format-ignore file based on the rules below:
+// - A blank line is skipped.
+// - Leading and trailing spaces of a line are trimmed.
+// - A line starting with a hash (`#`) is a comment.
+// - A non-comment line is a single pattern.
+// - 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).
+// - A pattern is negated if it starts with a bang (`!`).
+static bool isIgnored(StringRef FilePath) {
+  using namespace llvm::sys::fs;
+  if (!is_regular_file(FilePath))
+return false;
+
+  using namespace llvm::sys::path;
+  SmallString<128> Path, AbsPath{FilePath};
+
+  make_absolute(AbsPath);
+  remove_dots(AbsPath, /*remove_dot_dot=*/true);
+
+  StringRef IgnoreDir{AbsPath};
+  do {
+IgnoreDir = parent_path(IgnoreDir);
+if (IgnoreDir.empty())
+  return false;
+
+Path = IgnoreDir;
+append(Path, ".clang-format-ignore");
+  } while (!is_regular_file(Path));
+
+  std::ifstream IgnoreFile{Path.c_str()};
+  if (!IgnoreFile.good())
+return false;
+
+  AbsPath = convert_to_slash(AbsPath);
+

owenca wrote:

```suggestion
  const auto Pathname = convert_to_slash(AbsPath);
```

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


[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

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


@@ -570,6 +571,70 @@ static int dumpConfig(bool IsSTDIN) {
   return 0;
 }
 
+// Check whether `FilePath` is ignored according to the nearest
+// .clang-format-ignore file based on the rules below:
+// - A blank line is skipped.
+// - Leading and trailing spaces of a line are trimmed.
+// - A line starting with a hash (`#`) is a comment.
+// - A non-comment line is a single pattern.
+// - 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).
+// - A pattern is negated if it starts with a bang (`!`).
+static bool isIgnored(StringRef FilePath) {
+  using namespace llvm::sys::fs;
+  if (!is_regular_file(FilePath))
+return false;
+
+  using namespace llvm::sys::path;
+  SmallString<128> Path, AbsPath{FilePath};
+
+  make_absolute(AbsPath);
+  remove_dots(AbsPath, /*remove_dot_dot=*/true);
+
+  StringRef IgnoreDir{AbsPath};
+  do {
+IgnoreDir = parent_path(IgnoreDir);
+if (IgnoreDir.empty())
+  return false;
+
+Path = IgnoreDir;
+append(Path, ".clang-format-ignore");
+  } while (!is_regular_file(Path));
+
+  std::ifstream IgnoreFile{Path.c_str()};
+  if (!IgnoreFile.good())
+return false;
+
+  AbsPath = convert_to_slash(AbsPath);
+
+  for (std::string Line; std::getline(IgnoreFile, Line);) {
+auto Pattern = StringRef(Line).trim();
+if (Pattern.empty() || Pattern[0] == '#')
+  continue;
+
+const bool IsNegated = Pattern[0] == '!';
+if (IsNegated)
+  Pattern = Pattern.drop_front();
+
+if (Pattern.empty())
+  continue;
+
+Pattern = Pattern.ltrim();
+if (Pattern[0] != '/') {
+  Path = convert_to_slash(IgnoreDir);
+  append(Path, Style::posix, Pattern);
+  remove_dots(Path, /*remove_dot_dot=*/true, Style::posix);
+  Pattern = Path.str();
+}
+
+if (clang::format::matchFilePath(Pattern, AbsPath.str()) == !IsNegated)

owenca wrote:

```suggestion
if (clang::format::matchFilePath(Pattern, Pathname) == !IsNegated)
```

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


[clang] [clang-format] Fix handling of C-Style variable definition of a struct (PR #76344)

2023-12-29 Thread via cfe-commits

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


[llvm] [clang] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

[llvm] [clang] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 3e75dece919511e4a2edada82d783304cc14a9cd 
f6b6ca7f26e764b2c5088230a28e49b6d5ecdbb2 -- 
clang/include/clang/Basic/TargetInfo.h clang/lib/Basic/TargetInfo.cpp 
clang/lib/Basic/Targets/AArch64.cpp clang/lib/Basic/Targets/ARC.h 
clang/lib/Basic/Targets/AVR.h clang/lib/Basic/Targets/CSKY.h 
clang/lib/Basic/Targets/LoongArch.h clang/lib/Basic/Targets/MSP430.h 
clang/lib/Basic/Targets/Mips.h clang/lib/Basic/Targets/PPC.h 
clang/lib/Basic/Targets/RISCV.h clang/lib/Basic/Targets/Sparc.h 
clang/lib/Basic/Targets/SystemZ.h clang/lib/Basic/Targets/TCE.h 
clang/lib/Basic/Targets/VE.h clang/lib/Basic/Targets/WebAssembly.h 
clang/lib/Basic/Targets/X86.h clang/lib/Basic/Targets/XCore.h 
llvm/include/llvm/TargetParser/Triple.h llvm/lib/CodeGen/TargetLoweringBase.cpp 
llvm/lib/TargetParser/Triple.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 58c4de3bd7..f559b2a198 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -859,7 +859,7 @@ class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
 public:
   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
 const TargetOptions &Opts)
-  : WindowsX86_64TargetInfo(Triple, Opts) { }
+  : WindowsX86_64TargetInfo(Triple, Opts) {}
 
   void getTargetDefines(const LangOptions &Opts,
 MacroBuilder &Builder) const override {
@@ -879,7 +879,7 @@ class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
 : public WindowsX86_64TargetInfo {
 public:
   MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
-  : WindowsX86_64TargetInfo(Triple, Opts) { }
+  : WindowsX86_64TargetInfo(Triple, Opts) {}
 };
 
 // x86-64 Cygwin target
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 06fa61d5dd..33900dab08 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -1999,7 +1999,7 @@ Triple::CLayouts Triple::getCLayouts() const {
   Layouts.LongDoubleWidth = 128;
   Layouts.LongDoubleAlign = 128;
 }
-
+
 if (isOSDarwin()) {
   Layouts.LongDoubleWidth = 128;
   Layouts.LongDoubleAlign = 128;
@@ -2016,8 +2016,8 @@ Triple::CLayouts Triple::getCLayouts() const {
 Layouts.LongDoubleWidth = 64;
 Layouts.LongDoubleAlign = 64;
   } else if (isWindowsGNUEnvironment()) {
-// Mingw64 rounds long double size and alignment up to 16 bytes, but 
sticks
-// with x86 FP ops. Weird.
+// Mingw64 rounds long double size and alignment up to 16 bytes, but
+// sticks with x86 FP ops. Weird.
 Layouts.LongDoubleWidth = 128;
 Layouts.LongDoubleAlign = 128;
 Layouts.LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
@@ -2025,7 +2025,7 @@ Triple::CLayouts Triple::getCLayouts() const {
 Layouts.LongDoubleWidth = 64;
 Layouts.LongDoubleAlign = 64;
 Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble();
-  }  
+  }
 } else if (isOSIAMCU()) {
   Layouts.LongDoubleWidth = 64;
   Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble();

``




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


[llvm] [clang] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

[clang] [clang-format] Fix handling of C-Style variable definition of a struct (PR #76344)

2023-12-29 Thread via cfe-commits

https://github.com/XDeme updated https://github.com/llvm/llvm-project/pull/76344

>From a55c720f344645bdad3838aaa39b136c8b8ee6dc Mon Sep 17 00:00:00 2001
From: XDeme 
Date: Sun, 24 Dec 2023 20:18:02 -0300
Subject: [PATCH 1/4] [clang-format] Fix handling of C-Style variable
 definition of a struct

---
 clang/lib/Format/UnwrappedLineParser.cpp  | 8 
 clang/unittests/Format/FormatTest.cpp | 1 +
 clang/unittests/Format/TokenAnnotatorTest.cpp | 6 ++
 3 files changed, 15 insertions(+)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 684609747a5513..9cacb0d175adae 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3873,6 +3873,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
   const FormatToken &InitialToken = *FormatTok;
   nextToken();
 
+  int NonMacroIdentifierCount = 0;
   // The actual identifier can be a nested name specifier, and in macros
   // it is often token-pasted.
   // An [[attribute]] can be before the identifier.
@@ -3898,6 +3899,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
 FormatTok->is(tok::identifier) &&
 FormatTok->TokenText != FormatTok->TokenText.upper();
 nextToken();
+if (IsNonMacroIdentifier)
+  ++NonMacroIdentifierCount;
 // We can have macros in between 'class' and the class name.
 if (!IsNonMacroIdentifier && FormatTok->is(tok::l_paren))
   parseParens();
@@ -3960,6 +3963,11 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
 }
   };
   if (FormatTok->is(tok::l_brace)) {
+// Handles C-Style variable declaration of a struct
+if (Style.isCpp() && NonMacroIdentifierCount == 2) {
+  parseBracedList();
+  return;
+}
 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
 FormatTok->setFinalizedType(OpenBraceType);
 if (ParseAsExpr) {
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 762fc8254bdfc9..d37d1f58b51a4a 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -14548,6 +14548,7 @@ TEST_F(FormatTest, 
UnderstandContextOfRecordTypeKeywords) {
   verifyFormat("struct foo f() {}\nint n;");
   verifyFormat("class foo f() {}\nint n;");
   verifyFormat("union foo f() {}\nint n;");
+  verifyFormat("struct MACRO foo f{};");
 
   // Templates.
   verifyFormat("template  void f() {}\nint n;");
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp 
b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 2cafc0438ffb46..568574bf73a872 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -503,6 +503,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsVariables) {
   annotate("inline bool var = is_integral_v && is_signed_v;");
   EXPECT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator);
+
+  Tokens = annotate("struct Foo f{};");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown);
+  EXPECT_TOKEN(Tokens[2], tok::identifier, TT_StartOfName);
+  EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) {

>From 9e2e88495e86f040aeca2a0f0bc69bff3e6986e4 Mon Sep 17 00:00:00 2001
From: XDeme 
Date: Tue, 26 Dec 2023 14:11:09 -0300
Subject: [PATCH 2/4] Added support for templated structs

---
 clang/lib/Format/UnwrappedLineParser.cpp  | 13 +
 clang/unittests/Format/FormatTest.cpp |  3 ++-
 clang/unittests/Format/TokenAnnotatorTest.cpp |  6 ++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 9cacb0d175adae..e79eefd530451b 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3917,6 +3917,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
   // (this would still leave us with an ambiguity between template function
   // and class declarations).
   if (FormatTok->isOneOf(tok::colon, tok::less)) {
+int AngleNestingLevel = 0;
+bool ColonFound = false;
 do {
   if (FormatTok->is(tok::l_brace)) {
 calculateBraceTypes(/*ExpectClassBody=*/true);
@@ -3944,6 +3946,17 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
 parseCSharpGenericTypeConstraint();
 break;
   }
+  // Do not count identifiers inside a template angle brackets
+  if(FormatTok->is(tok::colon))
+ColonFound = true;
+  if (FormatTok->is(tok::less))
+++AngleNestingLevel;
+  else if (FormatTok->is(tok::greater))
+--AngleNestingLevel;
+  if (AngleNestingLevel == 0 && !ColonFound && 
FormatTok->is(tok::identifier) &&
+  FormatTok->TokenText != FormatTok->TokenText.upper()) {
+++NonMacroIdent

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

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

https://github.com/MaxEW707 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] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

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

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

https://github.com/MaxEW707 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] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

[clang] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

[clang] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

[clang] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 590f4920ceb1a80d711d39624b0249cd9ff774d2 Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..8a70786d97fe67
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-N

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

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

https://github.com/MaxEW707 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-29 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 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] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)

2023-12-29 Thread Trevor Gross via cfe-commits

https://github.com/tgross35 updated 
https://github.com/llvm/llvm-project/pull/76558

>From 7df4ef93989b1913d9200fbc29d6d04f9e59d51a Mon Sep 17 00:00:00 2001
From: Trevor Gross 
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/4] [IR] Add an xpassing test for `f128` intrinsic lowering

`f128` intrinsic functions lower to incorrect libc calls. Add a test
showing current behavior.
---
 .../CodeGen/Generic/f128-math-lowering.ll | 610 ++
 1 file changed, 610 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll

diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll 
b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 00..30efb8ef34918e
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,610 @@
+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+;;
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc < %s -mtriple=riscv32-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-RISCV32
+; RUN: llc < %s -mtriple=s390x-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-X64
+;
+; Verify that fp128 intrinsics only lower to `long double` calls on platforms
+; where `f128` and `long double` have the same layout.
+;
+; We test on x86 and x64 which have 80-bit ld, as well as aarch64 (ld == f128),
+; riscv32 (ld == f64), and s380x (ld == f128 with different alignment from
+; x64/aarch64 f128).
+;
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-LABEL:  test_cbrtf128:
+; CHECK-AARCH64:b llvm.cbrt.f128
+; CHECK-RISCV32:call llvm.cbrt.f128@plt
+; CHECK-S390X:  brasl {{%.*}} llvm.cbrt.f128@PLT
+; CHECK-X64:jmp llvm.cbrt.f128@PLT # TAILCALL
+; CHECK-X86:calll llvm.cbrt.f128@PLT
+start:
+  %0 = tail call fp128 @llvm.cbrt.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.cbrt.f128(fp128)
+
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL:  test_ceilf128:
+; CHECK-AARCH64:b ceill
+; CHECK-RISCV32:call ceill@plt
+; CHECK-S390X:  brasl {{%.*}} ceill@PLT
+; CHECK-X64:jmp ceill@PLT
+; CHECK-X86:calll ceill
+start:
+  %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.ceil.f128(fp128)
+
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; No math library call here, so make sure the assembly does the correct thing.
+; This test is autogenerated
+; CHECK-LABEL:test_copysignf128:
+; CHECK-AARCH64-LABEL: test_copysignf128:
+; CHECK-AARCH64:   // %bb.0: // %start
+; CHECK-AARCH64-NEXT:stp q0, q1, [sp, #-32]!
+; CHECK-AARCH64-NEXT:.cfi_def_cfa_offset 32
+; CHECK-AARCH64-NEXT:ldrb w8, [sp, #15]
+; CHECK-AARCH64-NEXT:ldrb w9, [sp, #31]
+; CHECK-AARCH64-NEXT:bfxil w9, w8, #0, #7
+; CHECK-AARCH64-NEXT:strb w9, [sp, #15]
+; CHECK-AARCH64-NEXT:ldr q0, [sp], #32
+; CHECK-AARCH64-NEXT:ret
+;
+; CHECK-RISCV32-LABEL: test_copysignf128:
+; CHECK-RISCV32:   # %bb.0: # %start
+; CHECK-RISCV32-NEXT:lw a3, 0(a1)
+; CHECK-RISCV32-NEXT:lw a4, 4(a1)
+; CHECK-RISCV32-NEXT:lw a2, 12(a2)
+; CHECK-RISCV32-NEXT:lw a5, 12(a1)
+; CHECK-RISCV32-NEXT:lw a1, 8(a1)
+; CHECK-RISCV32-NEXT:lui a6, 524288
+; CHECK-RISCV32-NEXT:and a2, a2, a6
+; CHECK-RISCV32-NEXT:slli a5, a5, 1
+; CHECK-RISCV32-NEXT:srli a5, a5, 1
+; CHECK-RISCV32-NEXT:or a2, a5, a2
+; CHECK-RISCV32-NEXT:sw a1, 8(a0)
+; CHECK-RISCV32-NEXT:sw a4, 4(a0)
+; CHECK-RISCV32-NEXT:sw a3, 0(a0)
+; CHECK-RISCV32-NEXT:sw a2, 12(a0)
+; CHECK-RISCV32-NEXT:ret
+;
+; CHECK-S390X-LABEL: test_copysignf128:
+; CHECK-S390X:   # %bb.0: # %start
+; CHECK-S390X-NEXT:ld %f0, 0(%r3)
+; CHECK-S390X-NEXT:ld %f2, 8(%r3)
+; CHECK-S390X-NEXT:ld %f1, 0(%r4)
+; CHECK-S390X-NEXT:ld %f3, 8(%r4)
+; CHECK-S390X-NEXT:cpsdr %f0, %f1, %f0
+; CHECK-S390X-NEXT:std %f0, 0(%r2)
+; CHECK-S390X-NEXT:std %f2, 8(%r2)
+; CHECK-S390X-NEXT:br %r14
+;
+; CHECK-X86-LABEL: test_copysignf128:
+; CHECK-X86:   # %bb.0: # %start
+; CHECK-X86-NEXT:pushl %ebx
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 8
+; CHECK-X86-NEXT:pushl %edi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 12
+; CHECK-X86-NEXT:pushl %esi
+; CHECK-X86-NEXT:.cfi_def_cfa_offset 16
+; CHECK-X86-NEXT:.cfi_offset %esi, -16
+; CHECK-X86-NEXT:.cfi_offset %edi, -12
+; CHECK-X86-NEXT:.cfi_offset %ebx, -8
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-X86-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-X86-

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

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

https://github.com/MaxEW707 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-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Max Winkler (MaxEW707)


Changes

 Background 

https://godbolt.org/z/hv53svTrq for reference on all of the below.

In games debug performance is critical as much as optimized performance. 
We mainly accomplish this by reducing the amount of function calls being made 
in debug builds. This does not imply the use of `always_inline` but mainly 
being diligent in the amount of small functions being called such as getters 
and accessor functions.
As has been gaining support the last couple years and shown by clangs builtin 
support there are a lot of language level features that are implemented in the 
standard library such as `std::move` which lead to poor debugging performance, 
experience and extra compile time due to template instantiations.
Since clang already treats these meta cast functions as implicit builtins I 
will assume the reasoning for such is already a given.

However us and many other game studios do not use the `std` and have our own 
core libraries and/or STL implementations. Therefore we do not get the benefits 
that clang provides by recognizing certain functions inside the `std` 
namespace. I will try to list some reasons why we cannot just include 
`` and use the std functions. I am happy to expand on those 
reasons in the comments if desired. The EASTL paper 
[here](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html) is 
a good starting point and still relevant today in my opinion.

 Use Case 

We have our own core libraries and STL implementation.
Internally our STL and core libraries use `static_cast` to implement move and 
forward semantics.
However almost all user code, the engine and games themselves, use the provided 
move and forward template function from these libraries.
Currently we have two variants due to historical reasons that will most likely 
never converge. One is inside a namespace like so `MySTL::move(...)` and one is 
prefixed as is done in C code like so `MyMove(...)`.

 ClangCL 

Last year MSVC added `[[msvc::intrinsic]]` for us game devs 
[here](https://github.com/MicrosoftDocs/cpp-docs/blob/main/docs/cpp/attributes.md#msvcintrinsic).
 This was explicitly added as an attribute under the request of us since a lot 
of us have custom STLs.
Clang currently lacks such an attribute which means we can't fully move onto 
`ClangCL` until we have a similar facility. It would also be helpful to have 
this attribute for our other platforms which are mostly console vendors who 
supply their own fork of clang but more on that below.

Besides the overloaded use of the word `intrinsic` one downside to this 
approach is that any warnings that could be generated by knowledge of `std` 
function implicit behaviours are not generated. Pessimizing move return 
warnings aren't generated.
This is still the case for our explicit core code that uses `static_cast` and 
something I plan to improve within Clang in the future.

 Force Inline Move 

To get around the GCC/Clang we do currently mark our move/forward functions as 
force inline which is respected in debug.
However as the godbolt shows the codegen isn't as good as the builtin in debug.
We still incur the compile-time cost compared to the builtin.

 Just use std 

While we might be able to use `std::move` via using declarations and macros 
that expand to `std::move` we cannot at all suffer the include times from 
vendor std implementations. Do note that we need to ship across different STL 
versions and vendor STLs that are not one of the major 3 public STLs that we 
all know.

MSVC STL shipped with MSVC 1938 takes 45ms to parse with clang.
libstdc++ shipped with Ubuntu 22.04 takes 31ms to parse with clang.
libc++ shipped with Ubuntu 22.04 takes 156ms to parse with clang.

We cannot include such costly headers into basically every single source file. 
We also don't want to balloon our PCH headers with expensive std includes and 
instead keep them for our internal includes as much as possible since the 
larger the PCH the slower your builds.
I haven't looked into `-fpch-instantiate-templates` yet or whether MSVC `/Yc` 
still has the same behaviour as `-fpch-instantiate-templates`. As MSVC gets 
more conforming and since we have to deal with vendor clang forks and vendor 
libraries, some which include templates in their headers, I don't want to be 
enforcing non-conforming defaults on our game teams using our core libraries.

 Just declare move 

Clang only looks for the declaration so we can just declare `move` inside the 
`std` namespace.
We have done this in the past however `libc++` started marking a bunch of 
functions with `abi_tag` which cannot be redeclared as shown in the godbolt.

We still need to ensure that our headers work with `std` headers included after 
us because there are some platform specific source files that need to interact 
with vendor or third party libraries who do use and include 

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

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

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

 Background 

https://godbolt.org/z/hv53svTrq for reference on all of the below.

In games debug performance is critical as much as optimized performance. 
We mainly accomplish this by reducing the amount of function calls being made 
in debug builds. This does not imply the use of `always_inline` but mainly 
being diligent in the amount of small functions being called such as getters 
and accessor functions.
As has been gaining support the last couple years and shown by clangs builtin 
support there are a lot of language level features that are implemented in the 
standard library such as `std::move` which lead to poor debugging performance, 
experience and extra compile time due to template instantiations.
Since clang already treats these meta cast functions as implicit builtins I 
will assume the reasoning for such is already a given.

However us and many other game studios do not use the `std` and have our own 
core libraries and/or STL implementations. Therefore we do not get the benefits 
that clang provides by recognizing certain functions inside the `std` 
namespace. I will try to list some reasons why we cannot just include 
`` and use the std functions. I am happy to expand on those reasons in 
the comments if desired. The EASTL paper 
[here](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html) is 
a good starting point and still relevant today in my opinion.

 Use Case 

We have our own core libraries and STL implementation.
Internally our STL and core libraries use `static_cast` to implement move and 
forward semantics.
However almost all user code, the engine and games themselves, use the provided 
move and forward template function from these libraries.
Currently we have two variants due to historical reasons that will most likely 
never converge. One is inside a namespace like so `MySTL::move(...)` and one is 
prefixed as is done in C code like so `MyMove(...)`.

 ClangCL 

Last year MSVC added `[[msvc::intrinsic]]` for us game devs 
[here](https://github.com/MicrosoftDocs/cpp-docs/blob/main/docs/cpp/attributes.md#msvcintrinsic).
 This was explicitly added as an attribute under the request of us since a lot 
of us have custom STLs.
Clang currently lacks such an attribute which means we can't fully move onto 
`ClangCL` until we have a similar facility. It would also be helpful to have 
this attribute for our other platforms which are mostly console vendors who 
supply their own fork of clang but more on that below.

Besides the overloaded use of the word `intrinsic` one downside to this 
approach is that any warnings that could be generated by knowledge of `std` 
function implicit behaviours are not generated. Pessimizing move return 
warnings aren't generated.
This is still the case for our explicit core code that uses `static_cast` and 
something I plan to improve within Clang in the future.

 Force Inline Move 

To get around the GCC/Clang we do currently mark our move/forward functions as 
force inline which is respected in debug.
However as the godbolt shows the codegen isn't as good as the builtin in debug.
We still incur the compile-time cost compared to the builtin.

 Just use std 

While we might be able to use `std::move` via using declarations and macros 
that expand to `std::move` we cannot at all suffer the include times from 
vendor std implementations. Do note that we need to ship across different STL 
versions and vendor STLs that are not one of the major 3 public STLs that we 
all know.

MSVC STL shipped with MSVC 1938 takes 45ms to parse with clang.
libstdc++ shipped with Ubuntu 22.04 takes 31ms to parse with clang.
libc++ shipped with Ubuntu 22.04 takes 156ms to parse with clang.

We cannot include such costly headers into basically every single source file. 
We also don't want to balloon our PCH headers with expensive std includes and 
instead keep them for our internal includes as much as possible since the 
larger the PCH the slower your builds.
I haven't looked into `-fpch-instantiate-templates` yet or whether MSVC `/Yc` 
still has the same behaviour as `-fpch-instantiate-templates`. As MSVC gets 
more conforming and since we have to deal with vendor clang forks and vendor 
libraries, some which include templates in their headers, I don't want to be 
enforcing non-conforming defaults on our game teams using our core libraries.

 Just declare move 

Clang only looks for the declaration so we can just declare `move` inside the 
`std` namespace.
We have done this in the past however `libc++` started marking a bunch of 
functions with `abi_tag` which cannot be redeclared as shown in the godbolt.

We still need to ensure that our headers work with `std` headers included after 
us because there are some platform specific source files that need to interact 
with vendor or third party libraries who do use and include `std` from t

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

2023-12-29 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();

DonatNagyE wrote:

I agree that the solution with the ternary operators is more readable. In 
particular, I like that it creates optional-like helper variables (in this case 
pointers that may be `nullptr`) instead of a `dyn_cast` that relies on a 
logical connection with a boolean helper variable.

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] Add build type to LibASTMatchersTutorial.rst cmake (PR #76301)

2023-12-29 Thread Craig Hesling via cfe-commits

linux4life798 wrote:

@tbaederr, thanks for the review! Can you merge the change or should I reach 
out to another reviewer?

Best,

Craig

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


[openmp] [clang] [llvm] [clang-tools-extra] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 commented:

Some quick nits, will look more later.

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


[openmp] [clang-tools-extra] [llvm] [clang] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Joseph Huber via cfe-commits


@@ -0,0 +1,21 @@
+//=== Profiling.h - OpenMP interface -- 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
+//
+//===--===//
+//
+//
+//===--===//
+
+#ifndef OMPTARGET_DEVICERTL_PROFILING_H
+#define OMPTARGET_DEVICERTL_PROFILING_H
+
+extern "C" {
+
+void __llvm_profile_register_function(void *ptr);
+void __llvm_profile_register_names_function(void *ptr, long int i);
+}
+

jhuber6 wrote:

```suggestion
void __llvm_profile_register_function(void *Ptr);
void __llvm_profile_register_names_function(void *Ptr, uint64_t I);

}

```

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


[clang-tools-extra] [llvm] [clang] [openmp] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Joseph Huber via cfe-commits


@@ -428,13 +428,22 @@ std::string getPGOFuncNameVarName(StringRef FuncName,
   return VarName;
 }
 
+bool isGPUProfTarget(const Module &M) {
+  const auto &triple = M.getTargetTriple();
+  return triple.rfind("nvptx", 0) == 0 || triple.rfind("amdgcn", 0) == 0 ||
+ triple.rfind("r600", 0) == 0;
+}
+

jhuber6 wrote:

```suggestion
bool isGPUProfTarget(const Module &M) {
  const llvm::Triple &Triple = M.getTargetTriple();
  return Triple.isAMDGPU() || Triple.isNVPTX()
}
```
Standard way looks like this. Side note, we really need a way to express this 
in a more re-usable way especially with SYCL looming. @arsenm should be make 
some common interface in `CodeGenModule` that just returns if we're currently 
targeting a "GPU like" device?

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


[openmp] [llvm] [clang] [clang-tools-extra] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Joseph Huber via cfe-commits


@@ -959,8 +959,14 @@ void CodeGenPGO::emitCounterIncrement(CGBuilderTy 
&Builder, const Stmt *S,
 
   unsigned Counter = (*RegionCounterMap)[S];
 
-  llvm::Value *Args[] = {FuncNameVar,
- Builder.getInt64(FunctionHash),
+  // Make sure that pointer to global is passed in with zero addrspace
+  // This is relevant during GPU profiling
+  auto *I8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+  auto *I8PtrTy = llvm::PointerType::getUnqual(I8Ty);
+  auto *NormalizedPtr = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+  FuncNameVar, I8PtrTy);
+

jhuber6 wrote:

```suggestion
  auto *NormalizedPtr = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
  FuncNameVar, llvm::PointerType::getUnqual(CGM.getLLVMContext());

```
LLVM uses opaque pointers for everything now.

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


[llvm] [clang-tools-extra] [openmp] [clang] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 edited 
https://github.com/llvm/llvm-project/pull/76587
___
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-29 Thread Gábor Spaits 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();
+if (FD->getTemplateSpecializationArgs()->size() < 1)

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

2023-12-29 Thread Gábor Spaits 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }

spaits wrote:

Now `setNullTypeAny` return a `ProgramStateRef` in which the type for that 
instance is null. Later the caller of the function can decide what to do with 
that.

The reason for storing null types is the possibility of an empty `std::any` 
instance. This is how the checker represents that. There is no type in the 
instance.

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-29 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 90802e652db348fd3218fcbfc3e6ac9e90702acd 
1a96db3c48782b0ec6f2de403ce862b9a95917bf -- 
clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp 
clang/test/Analysis/std-any-checker.cpp 
clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp 
clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h 
clang/test/Analysis/Inputs/system-header-simulator-cxx.h 
clang/test/Analysis/std-variant-checker.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
index df7b9c9c15..ef6a9268d9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
@@ -107,10 +107,11 @@ public:
 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 &C) 
const {
+  ProgramStateRef setNullTypeAny(const MemRegion *Mem,
+ CheckerContext &C) const {
 auto State = C.getState();
 return State->set(Mem, QualType{});
-//C.addTransition(State);
+// C.addTransition(State);
   }
 
   bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) const {

``




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-29 Thread Gábor Spaits 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"};

spaits wrote:

Added longer description and made it const.

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-29 Thread Boris Kolpackov via cfe-commits

boris-kolpackov wrote:

If I understand correctly, this invents a new option just to print the std 
modules path. Is there a reason why we cannot just print this information as 
part of `-print-search-dirs`? The benefit of this will be saving an extra 
compiler invocation in case the build system already uses this option, for 
example, to extract the library search paths (`build2` does this). BTW, this 
would also allow you to sidestep the whole "what to print if there is no path" 
issue -- just omit the entry from the output.

If for some reason a separate option is desirable, can we then also print this 
information as part of `-print-search-dirs`?

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-29 Thread Gábor Spaits via cfe-commits

https://github.com/spaits updated 
https://github.com/llvm/llvm-project/pull/76580

From 98b52eb390438402562de96a74771b0132fc71cb Mon Sep 17 00:00:00 2001
From: Gabor Spaits 
Date: Fri, 29 Dec 2023 17:54:34 +0100
Subject: [PATCH 1/7] [analyzer] Add std::any checker

---
 clang/docs/analyzer/checkers.rst  |  21 ++
 .../clang/StaticAnalyzer/Checkers/Checkers.td |   4 +
 .../StaticAnalyzer/Checkers/CMakeLists.txt|   1 +
 .../StaticAnalyzer/Checkers/StdAnyChecker.cpp | 201 ++
 .../Checkers/StdVariantChecker.cpp|  46 ++--
 .../Checkers/TaggedUnionModeling.h|   9 +-
 .../Inputs/system-header-simulator-cxx.h  |  59 +
 clang/test/Analysis/std-any-checker.cpp   | 170 +++
 clang/test/Analysis/std-variant-checker.cpp   |   8 +
 9 files changed, 490 insertions(+), 29 deletions(-)
 create mode 100644 clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
 create mode 100644 clang/test/Analysis/std-any-checker.cpp

diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index bb637cf1b8007b..867bdfc9012253 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -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.
+
+.. code-block:: cpp
+
+ void anyCast() {
+  std::any a = 5;
+  char c = std::any_cast(a); // // warn: "int" is the active alternative
+ }
+
+ void noTypeHeld() {
+  std::any a;
+  int i = std::any_cast(a); // warn: any 'a' is empty
+ }
+
 .. _alpha-core-StdVariant:
 
 alpha.core.StdVariant (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..954584fadb225d 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -321,6 +321,10 @@ def C11LockChecker : Checker<"C11Lock">,
   Dependencies<[PthreadLockBase]>,
   Documentation;
 
+def StdAnyChecker : Checker<"StdAny">,
+  HelpText<"Check for bad type access for std::any.">,
+  Documentation;
+
 def StdVariantChecker : Checker<"StdVariant">,
   HelpText<"Check for bad type access for std::variant.">,
   Documentation;
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..4e3475ff7f37da 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -107,6 +107,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   SmartPtrChecker.cpp
   SmartPtrModeling.cpp
   StackAddrEscapeChecker.cpp
+  StdAnyChecker.cpp
   StdLibraryFunctionsChecker.cpp
   StdVariantChecker.cpp
   STLAlgorithmModeling.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
new file mode 100644
index 00..647ee72e555140
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
@@ -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:
+  Progr

[clang] [clang-format] Fix handling of C-Style variable definition of a struct (PR #76344)

2023-12-29 Thread via cfe-commits

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


[clang-tools-extra] [llvm] [openmp] [clang] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-pgo

Author: Ethan Luis McDonough (EthanLuisMcDonough)


Changes

This pull request is the first part of an ongoing effort to extends PGO 
instrumentation to GPU device code. This PR makes the following changes:

- Adds blank registration functions to device RTL
- Gives PGO globals protected visibility when targeting a supported GPU
- Handles any addrspace casts for PGO calls
- Implements PGO global extraction in GPU plugins (currently only dumps info)

These changes can be tested by supplying `-fprofile-instrument=clang` while 
targeting a GPU.

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


11 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+8-2) 
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPKinds.def (+3) 
- (modified) llvm/include/llvm/ProfileData/InstrProf.h (+4) 
- (modified) llvm/lib/ProfileData/InstrProf.cpp (+15-2) 
- (modified) llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp (+26-7) 
- (modified) openmp/libomptarget/DeviceRTL/CMakeLists.txt (+2) 
- (added) openmp/libomptarget/DeviceRTL/include/Profiling.h (+21) 
- (added) openmp/libomptarget/DeviceRTL/src/Profiling.cpp (+19) 
- (modified) openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h 
(+27) 
- (modified) openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp 
(+82) 
- (modified) openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp 
(+14) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 81bf8ea696b164..edae6885b528ac 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -959,8 +959,14 @@ void CodeGenPGO::emitCounterIncrement(CGBuilderTy 
&Builder, const Stmt *S,
 
   unsigned Counter = (*RegionCounterMap)[S];
 
-  llvm::Value *Args[] = {FuncNameVar,
- Builder.getInt64(FunctionHash),
+  // Make sure that pointer to global is passed in with zero addrspace
+  // This is relevant during GPU profiling
+  auto *I8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+  auto *I8PtrTy = llvm::PointerType::getUnqual(I8Ty);
+  auto *NormalizedPtr = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+  FuncNameVar, I8PtrTy);
+
+  llvm::Value *Args[] = {NormalizedPtr, Builder.getInt64(FunctionHash),
  Builder.getInt32(NumRegionCounters),
  Builder.getInt32(Counter), StepV};
   if (!StepV)
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def 
b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index d22d2a8e948b00..1d887d5cb58127 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -503,6 +503,9 @@ __OMP_RTL(__kmpc_barrier_simple_generic, false, Void, 
IdentPtr, Int32)
 __OMP_RTL(__kmpc_warp_active_thread_mask, false, Int64,)
 __OMP_RTL(__kmpc_syncwarp, false, Void, Int64)
 
+__OMP_RTL(__llvm_profile_register_function, false, Void, VoidPtr)
+__OMP_RTL(__llvm_profile_register_names_function, false, Void, VoidPtr, Int64)
+
 __OMP_RTL(__last, false, Void, )
 
 #undef __OMP_RTL
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h 
b/llvm/include/llvm/ProfileData/InstrProf.h
index 36be2e7d869e7b..32648e4a67ad9e 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -171,6 +171,10 @@ inline StringRef getInstrProfCounterBiasVarName() {
 /// Return the marker used to separate PGO names during serialization.
 inline StringRef getInstrProfNameSeparator() { return "\01"; }
 
+/// Determines whether module targets a GPU eligable for PGO
+/// instrumentation
+bool isGPUProfTarget(const Module &M);
+
 /// Please use getIRPGOFuncName for LLVM IR instrumentation. This function is
 /// for front-end (Clang, etc) instrumentation.
 /// Return the modified name for function \c F suitable to be
diff --git a/llvm/lib/ProfileData/InstrProf.cpp 
b/llvm/lib/ProfileData/InstrProf.cpp
index 134a400e639c4b..cdcd6840bb5108 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -428,13 +428,22 @@ std::string getPGOFuncNameVarName(StringRef FuncName,
   return VarName;
 }
 
+bool isGPUProfTarget(const Module &M) {
+  const auto &triple = M.getTargetTriple();
+  return triple.rfind("nvptx", 0) == 0 || triple.rfind("amdgcn", 0) == 0 ||
+ triple.rfind("r600", 0) == 0;
+}
+
 GlobalVariable *createPGOFuncNameVar(Module &M,
  GlobalValue::LinkageTypes Linkage,
  StringRef PGOFuncName) {
+  // Ensure profiling variables on GPU are visible to be read from host
+  if (isGPUProfTarget(M))
+Linkage = GlobalValue::ExternalLinkage;
   // We generally want to match the function's linkage, but 
available_externally
   // and extern_weak both have the wrong semantics, and anything that doesn't
   // need to link across compilation units 

[openmp] [clang] [llvm] [clang-tools-extra] [PGO][OpenMP] Instrumentation for GPU devices (PR #76587)

2023-12-29 Thread Ethan Luis McDonough via cfe-commits

https://github.com/EthanLuisMcDonough created 
https://github.com/llvm/llvm-project/pull/76587

This pull request is the first part of an ongoing effort to extends PGO 
instrumentation to GPU device code. This PR makes the following changes:

- Adds blank registration functions to device RTL
- Gives PGO globals protected visibility when targeting a supported GPU
- Handles any addrspace casts for PGO calls
- Implements PGO global extraction in GPU plugins (currently only dumps info)

These changes can be tested by supplying `-fprofile-instrument=clang` while 
targeting a GPU.

>From 530eb982b9770190377bb0bd09c5cb715f34d484 Mon Sep 17 00:00:00 2001
From: Ethan Luis McDonough 
Date: Fri, 15 Dec 2023 20:38:38 -0600
Subject: [PATCH 1/5] Add profiling functions to libomptarget

---
 .../include/llvm/Frontend/OpenMP/OMPKinds.def |  3 +++
 openmp/libomptarget/DeviceRTL/CMakeLists.txt  |  2 ++
 .../DeviceRTL/include/Profiling.h | 21 +++
 .../libomptarget/DeviceRTL/src/Profiling.cpp  | 19 +
 4 files changed, 45 insertions(+)
 create mode 100644 openmp/libomptarget/DeviceRTL/include/Profiling.h
 create mode 100644 openmp/libomptarget/DeviceRTL/src/Profiling.cpp

diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def 
b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index d22d2a8e948b00..1d887d5cb58127 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -503,6 +503,9 @@ __OMP_RTL(__kmpc_barrier_simple_generic, false, Void, 
IdentPtr, Int32)
 __OMP_RTL(__kmpc_warp_active_thread_mask, false, Int64,)
 __OMP_RTL(__kmpc_syncwarp, false, Void, Int64)
 
+__OMP_RTL(__llvm_profile_register_function, false, Void, VoidPtr)
+__OMP_RTL(__llvm_profile_register_names_function, false, Void, VoidPtr, Int64)
+
 __OMP_RTL(__last, false, Void, )
 
 #undef __OMP_RTL
diff --git a/openmp/libomptarget/DeviceRTL/CMakeLists.txt 
b/openmp/libomptarget/DeviceRTL/CMakeLists.txt
index 1ce3e1e40a80ab..55ee15d068c67b 100644
--- a/openmp/libomptarget/DeviceRTL/CMakeLists.txt
+++ b/openmp/libomptarget/DeviceRTL/CMakeLists.txt
@@ -89,6 +89,7 @@ set(include_files
   ${include_directory}/Interface.h
   ${include_directory}/LibC.h
   ${include_directory}/Mapping.h
+  ${include_directory}/Profiling.h
   ${include_directory}/State.h
   ${include_directory}/Synchronization.h
   ${include_directory}/Types.h
@@ -104,6 +105,7 @@ set(src_files
   ${source_directory}/Mapping.cpp
   ${source_directory}/Misc.cpp
   ${source_directory}/Parallelism.cpp
+  ${source_directory}/Profiling.cpp
   ${source_directory}/Reduction.cpp
   ${source_directory}/State.cpp
   ${source_directory}/Synchronization.cpp
diff --git a/openmp/libomptarget/DeviceRTL/include/Profiling.h 
b/openmp/libomptarget/DeviceRTL/include/Profiling.h
new file mode 100644
index 00..68c7744cd60752
--- /dev/null
+++ b/openmp/libomptarget/DeviceRTL/include/Profiling.h
@@ -0,0 +1,21 @@
+//=== Profiling.h - OpenMP interface -- 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
+//
+//===--===//
+//
+//
+//===--===//
+
+#ifndef OMPTARGET_DEVICERTL_PROFILING_H
+#define OMPTARGET_DEVICERTL_PROFILING_H
+
+extern "C" {
+
+void __llvm_profile_register_function(void *ptr);
+void __llvm_profile_register_names_function(void *ptr, long int i);
+}
+
+#endif
diff --git a/openmp/libomptarget/DeviceRTL/src/Profiling.cpp 
b/openmp/libomptarget/DeviceRTL/src/Profiling.cpp
new file mode 100644
index 00..799477f5e47d27
--- /dev/null
+++ b/openmp/libomptarget/DeviceRTL/src/Profiling.cpp
@@ -0,0 +1,19 @@
+//===--- Profiling.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 "Profiling.h"
+
+#pragma omp begin declare target device_type(nohost)
+
+extern "C" {
+
+void __llvm_profile_register_function(void *ptr) {}
+void __llvm_profile_register_names_function(void *ptr, long int i) {}
+}
+
+#pragma omp end declare target

>From fb067d4ffe604fd68cf90b705db1942bce49dbb1 Mon Sep 17 00:00:00 2001
From: Ethan Luis McDonough 
Date: Sat, 16 Dec 2023 01:18:41 -0600
Subject: [PATCH 2/5] Fix PGO instrumentation for GPU targets

---
 clang/lib/CodeGen/CodeGenPGO.cpp  | 10 --
 .../lib/Transforms/Instrumentation/InstrProfiling.cpp | 11 ---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenPGO.

[clang] [clang-format] Add .clang-format-ignore for ignoring files (PR #76327)

2023-12-29 Thread Björn Schäpers via cfe-commits

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


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


[clang] [clang-format] Fix bad indentation with attribute and templated type (PR #76336)

2023-12-29 Thread Björn Schäpers via cfe-commits

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


[clang] 41ef6fc - [clang-format] Fix bad indentation with attribute and templated type (#76336)

2023-12-29 Thread via cfe-commits

Author: XDeme
Date: 2023-12-29T21:27:53+01:00
New Revision: 41ef6fc54f612000fe2e498b3931fa3229c7a78c

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

LOG: [clang-format] Fix bad indentation with attribute and templated type 
(#76336)

Fixes llvm/llvm-project#76314

Added: 


Modified: 
clang/lib/Format/ContinuationIndenter.cpp
clang/unittests/Format/FormatTest.cpp

Removed: 




diff  --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index 8489a30dd34ab3..102504182c4505 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -398,7 +398,7 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   }
   if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) ||
(Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
-Style.isCpp() &&
+State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() &&
 // FIXME: This is a temporary workaround for the case where 
clang-format
 // sets BreakBeforeParameter to avoid bin packing and this creates a
 // completely unnecessary line break after a template type that isn't

diff  --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 762fc8254bdfc9..881993ede17c3d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26295,6 +26295,8 @@ TEST_F(FormatTest, BreakAfterAttributes) {
   constexpr StringRef Code("[[maybe_unused]] const int i;\n"
"[[foo([[]])]] [[maybe_unused]]\n"
"int j;\n"
+   "[[maybe_unused]]\n"
+   "foo k;\n"
"[[nodiscard]] inline int f(int &i);\n"
"[[foo([[]])]] [[nodiscard]]\n"
"int g(int &i);\n"
@@ -26315,6 +26317,7 @@ TEST_F(FormatTest, BreakAfterAttributes) {
   Style.BreakAfterAttributes = FormatStyle::ABS_Never;
   verifyFormat("[[maybe_unused]] const int i;\n"
"[[foo([[]])]] [[maybe_unused]] int j;\n"
+   "[[maybe_unused]] foo k;\n"
"[[nodiscard]] inline int f(int &i);\n"
"[[foo([[]])]] [[nodiscard]] int g(int &i);\n"
"[[nodiscard]] inline int f(int &i) {\n"
@@ -26332,6 +26335,8 @@ TEST_F(FormatTest, BreakAfterAttributes) {
"const int i;\n"
"[[foo([[]])]] [[maybe_unused]]\n"
"int j;\n"
+   "[[maybe_unused]]\n"
+   "foo k;\n"
"[[nodiscard]]\n"
"inline int f(int &i);\n"
"[[foo([[]])]] [[nodiscard]]\n"



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


[clang] [clang-format] Fix bad indentation with attribute and templated type (PR #76336)

2023-12-29 Thread Björn Schäpers via cfe-commits

HazardyKnusperkeks wrote:

> Hi, Thanks for reviewing, could you merge this for me? I don't have write 
> access

I could. But I'm no fan of submitting just because one person approved without 
others having the chance to say something. (As has happened here.)

https://github.com/llvm/llvm-project/pull/76336
___
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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();
+if (FD->getTemplateSpecializationArgs()->size() < 1)

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

2023-12-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();
+if (FD->getTemplateSpecializationArgs()->size() < 1)

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

2023-12-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) const {

steakhal wrote:

The comment seems true, but inappropriate.

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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();
+if (FD->getTemplateSpecializationArgs()->size() < 1)

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

2023-12-29 Thread Balazs Benics 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"};

steakhal wrote:

You probably wanted some more sophisticated message here.
Also prefer `const` fields if possible.

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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();

steakhal wrote:

Both `CE` and `FD` dese

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

2023-12-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }

steakhal wrote:

I don't really like this `addTransition` here. This design limits composability.
Prefer calling this from one level above.

Also, why do we store Null types? Why don't we just drop the entry from the map?

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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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 &C) const {
+auto State = C.getState();
+State = State->set(Mem, QualType{});
+C.addTransition(State);
+  }
+
+  // this function name is terrible
+  bool handleAnyCastCall(const CallEvent &Call, CheckerContext &C) 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();

steakhal wrote:

Generally, `SVal::getType` should not be used, unless the corresponding 
expression is no longer accessible in code.
Prefer `Call.getArgExpr(0)->getType()->getPointeeType().getTypePtr()`  in this 
context.

`either` typo in the comment.

I'd also prefer a check and an early return if the type is neither a pointer 
not a reference. Make sure you check t

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

2023-12-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  return AsMemberOpCall->getCXXThisVal();
+}
+llvm_unreachable("We must have an assignment operator or constructor");
+  }();

steakhal wrote:

The immediately called lambda functions are generally not pretty.
I'd prefer (ab)using ternaries instead, like this:

```c++
const auto *AsCtorCall = dyn_cast_or_null(
AnyConstructor.matches(Call) ? &Call : nullptr);
const auto *AsAssignCall = dyn_cast_or_null(
AnyAsOp.matches(Call) ? &Call : nullptr);

if (!AsCtorCall && !AsAssignCall)
  return false;

SVal ThisSVal = AsCtorCall ? AsCtorCall->getCXXThisVal()
   : AsAssignCall->getCXXThisVal();
```

It might be only me, but I find this more readable.

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-29 Thread Balazs Benics via cfe-commits

https://github.com/steakhal 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-29 Thread Balazs Benics 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 
{

steakhal wrote:

We should prefer omitting params if not 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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  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(&Call);
+  return AsConstructorCall->getCXXThisVal();
+}
+if (IsAnyAssignmentOperatorCall) {
+  const auto *AsMemberOpCall = dyn_cast(&Call);
+  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

steakhal wrote:

Comments are capitalized and punctuated, as per llvm style.

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-29 Thread Balazs Benics via cfe-commits

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

First batch of review.

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-29 Thread Balazs Benics 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 &Call, CheckerContext &C) 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(&Call);
+  if (!AsMemberCall)
+return false;
+
+  const auto *ThisMemRegion = AsMemberCall->getCXXThisVal().getAsRegion();
+  if (!ThisMemRegion)
+return false;
+
+  setNullTypeAny(ThisMemRegion, C);
+  return true;

steakhal wrote:

This is probably a rare case when I'd prefer nesting ifs, or rather hoist this 
into a handler function and handle the "reset" call there. I'd prefer similar 
handlers for the rest of the APIs 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-29 Thread Balazs Benics via cfe-commits

https://github.com/steakhal 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][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker (PR #76557)

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

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

LGTM

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


[clang-tools-extra] [llvm] [clang] [analyzer] Trust base to derived casts for dynamic types (PR #69057)

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

steakhal wrote:

To illustrate the case of my previous argument, here are two examples:
https://godbolt.org/z/5vWadfPM9
```c++
// base.h BEGIN:
class Base {
public:
  virtual int fun() const = 0;
};

class Derived1 final : public Base {
public:
  int fun() const override { return 1; }
};
// base.h END

Base *spawn(); // Defined in "secondary.cpp"

template  void clang_analyzer_dump(T) {}

int main() {
Base *p = spawn();
int n = p->fun();
clang_analyzer_dump(n); // conj; and never "1"
int z = 100 / (n - 2);
(void)z;
}
```

And here is the example with definition of `spawn` inside a different 
translation unit, which would lead to a division by zero bug at the definition 
of `z`.
https://godbolt.org/z/eKMWvTPe6
```c++
// secondary.cpp
#include "base.h"
class Derived2 final : public Base {
public:
  int fun() const override { return 2; }
};

Base *spawn() {
return new Derived2();
}
```


https://github.com/llvm/llvm-project/pull/69057
___
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-29 Thread Ben Boeckel via cfe-commits


@@ -2164,6 +2164,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
 return false;
   }
 
+  if (C.getArgs().hasArg(options::OPT_print_library_module_manifest_path)) {
+llvm::outs() << "module: ="

mathstuf wrote:

I suppose that's good enough; we also don't get reasons why `-stdlib=libstdc++` 
fails due to non-install either.

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-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Gábor Spaits (spaits)


Changes

Add a checker to detect bad `std::any` type accesses.
It warns, when the active type is different from the requested type when 
calling `std::any_cast`:
```cpp
void anyCast() {
  std::any a = 5;
  char c = std::any_cast(a); // // warn: "int" is the active 
alternative
 }
```
It also warns, when the `std::any` instance is empty:
```cpp
 void noTypeHeld() {
  std::any a;
  int i = std::any_cast(a); // warn: any 'a' is empty
 }
```
This checker works in a similar way to `std::variant` checker: Recognizes when 
the active type of an `std::any` instance changes and stores this information. 
Later on, when the data hold in this instance is accessed with `std::any_cast` 
it is checked if the active type is retrieved or not. If not then a warning is 
emitted.

This checker does not produce false positives. It is conservative: if there is 
no information of the `std::any` instance or the already recorded information 
becomes invalid no report will be emitted. 

---

Patch is 20.77 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/76580.diff


9 Files Affected:

- (modified) clang/docs/analyzer/checkers.rst (+21) 
- (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+4) 
- (modified) clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt (+1) 
- (added) clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp (+201) 
- (modified) clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp (+23-23) 
- (modified) clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h (+3-6) 
- (modified) clang/test/Analysis/Inputs/system-header-simulator-cxx.h (+59) 
- (added) clang/test/Analysis/std-any-checker.cpp (+170) 
- (modified) clang/test/Analysis/std-variant-checker.cpp (+8) 


``diff
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index bb637cf1b8007b..867bdfc9012253 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -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.
+
+.. code-block:: cpp
+
+ void anyCast() {
+  std::any a = 5;
+  char c = std::any_cast(a); // // warn: "int" is the active alternative
+ }
+
+ void noTypeHeld() {
+  std::any a;
+  int i = std::any_cast(a); // warn: any 'a' is empty
+ }
+
 .. _alpha-core-StdVariant:
 
 alpha.core.StdVariant (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..954584fadb225d 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -321,6 +321,10 @@ def C11LockChecker : Checker<"C11Lock">,
   Dependencies<[PthreadLockBase]>,
   Documentation;
 
+def StdAnyChecker : Checker<"StdAny">,
+  HelpText<"Check for bad type access for std::any.">,
+  Documentation;
+
 def StdVariantChecker : Checker<"StdVariant">,
   HelpText<"Check for bad type access for std::variant.">,
   Documentation;
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..4e3475ff7f37da 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -107,6 +107,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   SmartPtrChecker.cpp
   SmartPtrModeling.cpp
   StackAddrEscapeChecker.cpp
+  StdAnyChecker.cpp
   StdLibraryFunctionsChecker.cpp
   StdVariantChecker.cpp
   STLAlgorithmModeling.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
new file mode 100644
index 00..647ee72e555140
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
@@ -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"
+#i

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

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

https://github.com/spaits created 
https://github.com/llvm/llvm-project/pull/76580

Add a checker to detect bad `std::any` type accesses.
It warns, when the active type is different from the requested type when 
calling `std::any_cast`:
```cpp
void anyCast() {
  std::any a = 5;
  char c = std::any_cast(a); // // warn: "int" is the active alternative
 }
```
It also warns, when the `std::any` instance is empty:
```cpp
 void noTypeHeld() {
  std::any a;
  int i = std::any_cast(a); // warn: any 'a' is empty
 }
```
This checker works in a similar way to `std::variant` checker: Recognizes when 
the active type of an `std::any` instance changes and stores this information. 
Later on, when the data hold in this instance is accessed with `std::any_cast` 
it is checked if the active type is retrieved or not. If not then a warning is 
emitted.

This checker does not produce false positives. It is conservative: if there is 
no information of the `std::any` instance or the already recorded information 
becomes invalid no report will be emitted. 

From 98b52eb390438402562de96a74771b0132fc71cb Mon Sep 17 00:00:00 2001
From: Gabor Spaits 
Date: Fri, 29 Dec 2023 17:54:34 +0100
Subject: [PATCH] [analyzer] Add std::any checker

---
 clang/docs/analyzer/checkers.rst  |  21 ++
 .../clang/StaticAnalyzer/Checkers/Checkers.td |   4 +
 .../StaticAnalyzer/Checkers/CMakeLists.txt|   1 +
 .../StaticAnalyzer/Checkers/StdAnyChecker.cpp | 201 ++
 .../Checkers/StdVariantChecker.cpp|  46 ++--
 .../Checkers/TaggedUnionModeling.h|   9 +-
 .../Inputs/system-header-simulator-cxx.h  |  59 +
 clang/test/Analysis/std-any-checker.cpp   | 170 +++
 clang/test/Analysis/std-variant-checker.cpp   |   8 +
 9 files changed, 490 insertions(+), 29 deletions(-)
 create mode 100644 clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
 create mode 100644 clang/test/Analysis/std-any-checker.cpp

diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index bb637cf1b8007b..867bdfc9012253 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -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.
+
+.. code-block:: cpp
+
+ void anyCast() {
+  std::any a = 5;
+  char c = std::any_cast(a); // // warn: "int" is the active alternative
+ }
+
+ void noTypeHeld() {
+  std::any a;
+  int i = std::any_cast(a); // warn: any 'a' is empty
+ }
+
 .. _alpha-core-StdVariant:
 
 alpha.core.StdVariant (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..954584fadb225d 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -321,6 +321,10 @@ def C11LockChecker : Checker<"C11Lock">,
   Dependencies<[PthreadLockBase]>,
   Documentation;
 
+def StdAnyChecker : Checker<"StdAny">,
+  HelpText<"Check for bad type access for std::any.">,
+  Documentation;
+
 def StdVariantChecker : Checker<"StdVariant">,
   HelpText<"Check for bad type access for std::variant.">,
   Documentation;
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..4e3475ff7f37da 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -107,6 +107,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   SmartPtrChecker.cpp
   SmartPtrModeling.cpp
   StackAddrEscapeChecker.cpp
+  StdAnyChecker.cpp
   StdLibraryFunctionsChecker.cpp
   StdVariantChecker.cpp
   STLAlgorithmModeling.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
new file mode 100644
index 00..647ee72e555140
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/StdAnyChecker.cpp
@@ -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"

[llvm] [clang] [RISCV] Add MC layer support for Zicfiss. (PR #66043)

2023-12-29 Thread Craig Topper via cfe-commits

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

LGTM

https://github.com/llvm/llvm-project/pull/66043
___
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-29 Thread Craig Topper via cfe-commits

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

LGTM other than the comment about the commit message

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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

2023-12-29 Thread Craig Topper via cfe-commits

https://github.com/topperc commented:

LGTM other than the comment about the commit message

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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

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

michaelmaitland wrote:

> > The 'b' character is specified to use 'b'.
> 
> Was this sentence supposed to say `bool`?

yes, updated.

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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

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

https://github.com/michaelmaitland edited 
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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

2023-12-29 Thread Craig Topper via cfe-commits

topperc wrote:

> The 'b' character is specified to use 'b'. 

Was this sentence supposed to say `bool`?

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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

2023-12-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-risc-v

Author: Michael Maitland (michaelmaitland)


Changes

Builtins.def says that bfloat should be represented by the 'y' character, not 
the 'b' character. The 'b' character is specified to use 'b'. 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.

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


4 Files Affected:

- (modified) clang/include/clang/Basic/riscv_sifive_vector.td (+1-1) 
- (modified) clang/include/clang/Basic/riscv_vector_common.td (+1-1) 
- (modified) clang/lib/Support/RISCVVIntrinsicUtils.cpp (+1-1) 
- (modified) clang/utils/TableGen/RISCVVEmitter.cpp (+1-1) 


``diff
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:

``




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] [Clang][RISCV] bfloat uses 'y' instead of 'b' (PR #76575)

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

https://github.com/michaelmaitland created 
https://github.com/llvm/llvm-project/pull/76575

Builtins.def says that bfloat should be represented by the 'y' character, not 
the 'b' character. The 'b' character is specified to use 'b'. 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.

>From 913ad0a5fc48429cdcd09bdbff88023427813760 Mon Sep 17 00:00:00 2001
From: Michael Maitland 
Date: Fri, 29 Dec 2023 10:11:34 -0800
Subject: [PATCH] [Clang][RISCV] bfloat uses 'y' instead of 'b'

Builtins.def says that bfloat should be represented by the 'y'
character, not the 'b' character. The 'b' character is specified to use
'b'. 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.
---
 clang/include/clang/Basic/riscv_sifive_vector.td | 2 +-
 clang/include/clang/Basic/riscv_vector_common.td | 2 +-
 clang/lib/Support/RISCVVIntrinsicUtils.cpp   | 2 +-
 clang/utils/TableGen/RISCVVEmitter.cpp   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

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] [clang] Sema::isSimpleTypeSpecifier return true for _Bool in c99 (PR #72204)

2023-12-29 Thread Carl Peto via cfe-commits

carlos4242 wrote:

Hi @AaronBallman what do you think about this PR? Is it good to merge or is 
there something else I can add?

https://github.com/llvm/llvm-project/pull/72204
___
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-29 Thread Carl Peto via cfe-commits

carlos4242 wrote:

@benshi001 Have you got any thoughts on this as the AVR maintainer? I've been 
using various versions of this patch in my own branches for years. Should we 
merge?

I think ultimately it's your call as you're the AVR backend owner?

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] [OpenMP][USM] Introduces -fopenmp-force-usm flag (PR #76571)

2023-12-29 Thread Jan Patrick Lehr via cfe-commits

jplehr wrote:

> > Is the approach taken in this approach acceptable as opposed to the header 
> > solution I put up earlier?
> 
> Yes, it's pretty much exactly what I had in mind from my suggestion in the 
> last PR. Thanks.

Perfect. I'll go ahead and add lit and runtime tests.

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


[clang] [OpenMP][USM] Introduces -fopenmp-force-usm flag (PR #76571)

2023-12-29 Thread Joseph Huber via cfe-commits

jhuber6 wrote:

> Is the approach taken in this approach acceptable as opposed to the header 
> solution I put up earlier?

Yes, it's pretty much exactly what I had in mind from my suggestion in the last 
PR. Thanks.

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


[clang] [OpenMP][USM] Introduces -fopenmp-force-usm flag (PR #76571)

2023-12-29 Thread Jan Patrick Lehr via cfe-commits

jplehr wrote:

Is the approach taken in this approach acceptable as opposed to the header 
solution I put up earlier?

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


[clang] [OpenMP][USM] Introduces -fopenmp-force-usm flag (PR #76571)

2023-12-29 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 commented:

Needs a test. There should be some difference in codegen we can key off of.

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


[clang] [llvm] [clang-tools-extra] [analyzer] Trust base to derived casts for dynamic types (PR #69057)

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


@@ -492,11 +492,13 @@ void check_required_cast() {
 
 void check_cast_behavior(OSObject *obj) {
   OSArray *arr1 = OSDynamicCast(OSArray, obj);
-  clang_analyzer_eval(arr1 == obj); // expected-warning{{TRUE}}
-// expected-note@-1{{TRUE}}
-// expected-note@-2{{Assuming 'arr1' is 
not equal to 'obj'}}
-// expected-warning@-3{{FALSE}}
-// expected-note@-4   {{FALSE}}
+  clang_analyzer_eval(arr1 == obj); // #check_cast_behavior_1
+  // expected-warning@#check_cast_behavior_1 {{TRUE}}
+  // expected-note@#check_cast_behavior_1{{TRUE}}
+  // expected-note@#check_cast_behavior_1{{Assuming 'arr1' is equal to 'obj'}}

steakhal wrote:

I went back to this comment to double check, and I can confirm what's happening.
On the baseline revision, the node for `clang_analyzer_eval(arr2 == obj)` has 
two parents:
1) Where `arr2` is known to be `0 (loc)`, by an eager assumption by 
`clang_analyzer_eval(arr1 == obj)`.
2) Where `arr2` is known to be non-null, by the same eager assumption. However, 
for this we already had a message as `Assuming 'arr1' is not equal to 'obj'` 
(see the baseline test).

After this PR, the exploded graph would no longer have two parents for the 
given bug-report, so it can't couldn't chose the same parent node in the 
exploded graph when constructing the bug report. This means that on that path, 
it will see an eager assumption to `true`, and craft a piece message 
accordingly.

This means, that the bug report construction could have chosen the other parent 
for constructing the bug report, and have the same behavior as demonstrated 
after the PR.

The next question could be, why are the following exploded nodes not merged 
after this PR?
![image](https://github.com/llvm/llvm-project/assets/6280485/9cbd2c7c-e3fe-4186-b09e-8aa5d12dbf50)
![image](https://github.com/llvm/llvm-project/assets/6280485/b999a938-82fc-485d-9780-ffb9e1594539)


On the baseline it looks like this, (notice the two parents):
![image](https://github.com/llvm/llvm-project/assets/6280485/eff9d0f0-4f17-4e83-9404-320fa50ed6fa)


---

Anyways, this debunks the theory that this PR changes this test in any 
meaningful/practical ways - as far as I can see it.

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


  1   2   >