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

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

https://github.com/benshi001 created 
https://github.com/llvm/llvm-project/pull/76557

None

>From 2eebb462b8a7865684d3baaffbad7560eed10e57 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 29 Dec 2023 16:44:47 +0800
Subject: [PATCH] [clang][analyzer] Support 'fflush' in the
 StdLibraryFunctionsChecker

---
 .../Checkers/StdLibraryFunctionsChecker.cpp   |  8 ++
 clang/test/Analysis/stream-errno.c| 26 +++
 2 files changed, 34 insertions(+)

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..d52480741d4cd1 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_0(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_1(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] [clang][analyzer] Support 'fflush' in the StdLibraryFunctionsChecker (PR #76557)

2023-12-29 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Ben Shi (benshi001)


Changes



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


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp 
(+8) 
- (modified) clang/test/Analysis/stream-errno.c (+26) 


``diff
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..d52480741d4cd1 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_0(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_1(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
+  }
+}

``




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


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

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

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

Currently `fp128` math intrinsics are lowered to functions expecting `long 
double`, which is a problem when `long double` and `f128` do not have the same 
layout (e.g. `long double` on x86 is `f80`).

This patchset does the following:

1. Move `long double` layout logic from Clang to LLVM so we can use it on all 
targets
2. Default to lowering to `__float128` math calls rather than `long double` 
calls (`sinf128` instead of `sinl`)
3. Add logic to still emit long double calls on platforms where `long double == 
f128`, 

I still need to figure out how to support `-mlong-double-128` and similar 
flags, and need to add a test for a target where `ld == f128` such as aarch64. 
A quick review at this point would still be appreciated to make sure I am on 
the right track.

Fixes: https://github.com/llvm/llvm-project/issues/44744
Discourse discussion: 
https://discourse.llvm.org/t/fp128-math-functions-strange-results/72708
Initial patchset: https://reviews.llvm.org/D157836 / 
http://108.170.204.19/D157836


>From 2f0f7c829a3ba16e7f1fa5a434832e07c40c1f1c 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.
---
 llvm/test/CodeGen/X86/f128-arith.ll | 516 
 1 file changed, 516 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/f128-arith.ll

diff --git a/llvm/test/CodeGen/X86/f128-arith.ll 
b/llvm/test/CodeGen/X86/f128-arith.ll
new file mode 100644
index 00..6af56a78b2926f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/f128-arith.ll
@@ -0,0 +1,516 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 2
+; RUN: llc < %s -mtriple=i686-unknown-unknown   -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | 
FileCheck %s --check-prefix=CHECK-64
+;
+; Test lowering of fp128 intrinsics
+; FIXME: these emit calls to long double functions but should emit f128 calls
+
+define fp128 @test_cbrtf128(fp128 %a) {
+; CHECK-32-LABEL: test_cbrtf128:
+; CHECK-32:calll llvm.cbrt.f128@PLT
+;
+; CHECK-64-LABEL: test_cbrtf128:
+; CHECK-64:jmp llvm.cbrt.f128@PLT # TAILCALL
+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-32-LABEL: test_ceilf128:
+; CHECK-32:calll ceill
+;
+; CHECK-64-LABEL: test_ceilf128:
+; CHECK-64:jmp ceill@PLT # TAILCALL
+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) {
+; CHECK-32-LABEL: test_copysignf128:
+; CHECK-32:   # %bb.0: # %start
+; CHECK-32-NEXT:pushl %ebx
+; CHECK-32-NEXT:.cfi_def_cfa_offset 8
+; CHECK-32-NEXT:pushl %edi
+; CHECK-32-NEXT:.cfi_def_cfa_offset 12
+; CHECK-32-NEXT:pushl %esi
+; CHECK-32-NEXT:.cfi_def_cfa_offset 16
+; CHECK-32-NEXT:.cfi_offset %esi, -16
+; CHECK-32-NEXT:.cfi_offset %edi, -12
+; CHECK-32-NEXT:.cfi_offset %ebx, -8
+; CHECK-32-NEXT:movl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:movl {{[0-9]+}}(%esp), %ecx
+; CHECK-32-NEXT:movl {{[0-9]+}}(%esp), %edx
+; CHECK-32-NEXT:movl {{[0-9]+}}(%esp), %esi
+; CHECK-32-NEXT:movl $-2147483648, %edi # imm = 0x8000
+; CHECK-32-NEXT:andl {{[0-9]+}}(%esp), %edi
+; CHECK-32-NEXT:movl $2147483647, %ebx # imm = 0x7FFF
+; CHECK-32-NEXT:andl {{[0-9]+}}(%esp), %ebx
+; CHECK-32-NEXT:orl %edi, %ebx
+; CHECK-32-NEXT:movl %ebx, 12(%eax)
+; CHECK-32-NEXT:movl %esi, 8(%eax)
+; CHECK-32-NEXT:movl %edx, 4(%eax)
+; CHECK-32-NEXT:movl %ecx, (%eax)
+; CHECK-32-NEXT:popl %esi
+; CHECK-32-NEXT:.cfi_def_cfa_offset 12
+; CHECK-32-NEXT:popl %edi
+; CHECK-32-NEXT:.cfi_def_cfa_offset 8
+; CHECK-32-NEXT:popl %ebx
+; CHECK-32-NEXT:.cfi_def_cfa_offset 4
+; CHECK-32-NEXT:retl $4
+;
+; CHECK-64-LABEL: test_copysignf128:
+; CHECK-64:   # %bb.0: # %start
+; CHECK-64-NEXT:andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; CHECK-64-NEXT:andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-64-NEXT:orps %xmm1, %xmm0
+; CHECK-64-NEXT:retq
+; FIXME: calling long double rather than f128 function
+; FIXME: calling long double rather than f128 function
+start:
+  %0 = tail call fp128 @llvm.copysign.f128(fp128 %a, fp128 %b)
+  ret fp128 %0
+}
+
+declare fp128 @llvm.copysign.f128(fp128, fp128)
+
+
+define fp128 @test_cosf128(fp128 %a) {
+; CHECK-32-LABEL: test_cosf128:
+; CHECK-32:calll cosl
+;
+; CHECK-64-LABEL: test_cosf128:
+; CHECK-64:jmp cosl@PLT # TAILCALL
+start:
+  %0 = tail call fp128 @llvm.cos.f128(fp128 %a)
+  ret fp128 %0

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

2023-12-29 Thread via cfe-commits

github-actions[bot] wrote:

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

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

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

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

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

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

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

https://github.com/llvm/llvm-project/pull/76558
___
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

tgross35 wrote:

@efriedma-quic was looking at this on phabricator

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


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

2023-12-29 Thread via cfe-commits

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

Looks good to me, my only nitpick is that perhaps you could use more 
descriptive test names instead of distinguishing them with `_0` and `_1` 
suffixes.

Also, perhaps wait a bit (until next year ;) ) before merging this to give 
other reviewers a chance to look at it.

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

https://github.com/DonatNagyE edited 
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 Balazs Benics via cfe-commits

steakhal wrote:

please also update the release notes

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

https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/76557

>From 2eebb462b8a7865684d3baaffbad7560eed10e57 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 29 Dec 2023 16:44:47 +0800
Subject: [PATCH 1/2] [clang][analyzer] Support 'fflush' in the
 StdLibraryFunctionsChecker

---
 .../Checkers/StdLibraryFunctionsChecker.cpp   |  8 ++
 clang/test/Analysis/stream-errno.c| 26 +++
 2 files changed, 34 insertions(+)

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..d52480741d4cd1 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_0(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_1(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
+  }
+}

>From 3c0f61c3d317e2c4bcff77532677b68c9bc0e01a Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Fri, 29 Dec 2023 11:01:01 +0100
Subject: [PATCH 2/2] Update the release notes

---
 clang/docs/ReleaseNotes.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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

___
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 updated 
https://github.com/llvm/llvm-project/pull/76557

>From 2eebb462b8a7865684d3baaffbad7560eed10e57 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 29 Dec 2023 16:44:47 +0800
Subject: [PATCH 1/3] [clang][analyzer] Support 'fflush' in the
 StdLibraryFunctionsChecker

---
 .../Checkers/StdLibraryFunctionsChecker.cpp   |  8 ++
 clang/test/Analysis/stream-errno.c| 26 +++
 2 files changed, 34 insertions(+)

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..d52480741d4cd1 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_0(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_1(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
+  }
+}

>From 3c0f61c3d317e2c4bcff77532677b68c9bc0e01a Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Fri, 29 Dec 2023 11:01:01 +0100
Subject: [PATCH 2/3] Update the release notes

---
 clang/docs/ReleaseNotes.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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

>From f294a949aa5f95e4731fe1bb9d6f51865bc35357 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 29 Dec 2023 18:21:10 +0800
Subject: [PATCH 3/3] Rename the test function names

---
 clang/test/Analysis/stream-errno.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Analysis/stream-errno.c 
b/clang/test/Analysis/stream-errno.c
index d52480741d4cd1..f44ee6070708b2 100644
--- a/clang/test/Analysis/stream-errno.c
+++ b/clang/test/Analysis/stream-errno.c
@@ -223,7 +223,7 @@ void check_fileno(void) {
   if (errno) {} // expected-warning{{An undefined value may be read from 
'errno'}}
 }
 
-void check_fflush_0(void) {
+void check_fflush_opened_file(void) {
   FILE *F = tmpfile();
   if (!F)
 return;
@@ -238,7 +238,7 @@ void check_fflush_0(void) {
   fclose(F);
 }
 
-void check_fflush_1(void) {
+void check_fflush_all(void) {
   int N = fflush(NULL);
   if (N == 0) {
 if (errno) {}// expected-warning{{An undefined value 
may be read from 'errno'}}

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

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

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

benshi001 wrote:

> Looks good to me, my only nitpick is that perhaps you could use more 
> descriptive test names instead of using `_0` and `_1` suffixes.
> 
> Also, perhaps wait a bit (until next year ;) ) before merging this to give 
> other reviewers a chance to look at it.

Thanks for your suggestion. I have renamed the test functions to more 
meaningful names.

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

benshi001 wrote:

> ~please also update the release notes~ EDIT: Done.

Thanks for your support!

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] Correctly implement CWG 2672 (PR #75001)

2023-12-29 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

DR test changes look good to me, but wait for another reviewer.

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


[clang] [clang][AVR] Restrict range of assembly constraint 'G' (PR #76561)

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

https://github.com/benshi001 created 
https://github.com/llvm/llvm-project/pull/76561

According to https://www.nongnu.org/avr-libc/user-manual/inline_asm.html, "G" 
only represent a float constraint "0.0". And avr-gcc also rejects other 
non-zero values.

>From 0a29621f6c6808668ada014313083f45a601f33b Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 29 Dec 2023 17:58:21 +0800
Subject: [PATCH] [clang][AVR] Restrict range of assembly constraint 'G'

According to https://www.nongnu.org/avr-libc/user-manual/inline_asm.html,
"G" only represent a float constraint "0.0". And avr-gcc also rejects
other non-zero values.
---
 clang/lib/Basic/Targets/AVR.h | 4 +++-
 clang/test/CodeGen/avr/avr-inline-asm-constraints.c   | 4 ++--
 .../test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c | 1 +
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h
index 854a51d78c393b..9376c46cd98ca1 100644
--- a/clang/lib/Basic/Targets/AVR.h
+++ b/clang/lib/Basic/Targets/AVR.h
@@ -146,7 +146,9 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public 
TargetInfo {
 case 'R': // Integer constant (Range: -6 to 5)
   Info.setRequiresImmediate(-6, 5);
   return true;
-case 'G': // Floating point constant
+case 'G': // Floating point constant 0.0
+  Info.setRequiresImmediate(0);
+  return true;
 case 'Q': // A memory address based on Y or Z pointer with displacement.
   return true;
 }
diff --git a/clang/test/CodeGen/avr/avr-inline-asm-constraints.c 
b/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
index 96774861feb228..3a956de8db48f0 100644
--- a/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
+++ b/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
@@ -109,8 +109,8 @@ void R() {
 }
 
 void G() {
-  // CHECK: call addrspace(0) void asm sideeffect "subi r30, $0", "G"(i16 50)
-  asm("subi r30, %0" :: "G"(50));
+  // CHECK: call addrspace(0) void asm sideeffect "subi r30, $0", "G"(i16 0)
+  asm("subi r30, %0" :: "G"(0));
 }
 
 void Q() {
diff --git a/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c 
b/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
index ceea59229f736a..29f0b69285fa88 100644
--- a/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
+++ b/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
@@ -5,4 +5,5 @@ const unsigned char val = 0;
 int foo(void) {
   __asm__ volatile("foo %0, 1" : : "fo" (val)); // expected-error {{invalid 
input constraint 'fo' in asm}}
   __asm__ volatile("foo %0, 1" : : "Nd" (val)); // expected-error {{invalid 
input constraint 'Nd' in asm}}
+  __asm__ volatile("subi r30, %0" : : "G" (1)); // expected-error {{value '1' 
out of range for constraint 'G'}}
 }

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


[clang] [clang][AVR] Restrict range of assembly constraint 'G' (PR #76561)

2023-12-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Ben Shi (benshi001)


Changes

According to https://www.nongnu.org/avr-libc/user-manual/inline_asm.html, "G" 
only represent a float constraint "0.0". And avr-gcc also rejects other 
non-zero values.

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


3 Files Affected:

- (modified) clang/lib/Basic/Targets/AVR.h (+3-1) 
- (modified) clang/test/CodeGen/avr/avr-inline-asm-constraints.c (+2-2) 
- (modified) clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c 
(+1) 


``diff
diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h
index 854a51d78c393b..9376c46cd98ca1 100644
--- a/clang/lib/Basic/Targets/AVR.h
+++ b/clang/lib/Basic/Targets/AVR.h
@@ -146,7 +146,9 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public 
TargetInfo {
 case 'R': // Integer constant (Range: -6 to 5)
   Info.setRequiresImmediate(-6, 5);
   return true;
-case 'G': // Floating point constant
+case 'G': // Floating point constant 0.0
+  Info.setRequiresImmediate(0);
+  return true;
 case 'Q': // A memory address based on Y or Z pointer with displacement.
   return true;
 }
diff --git a/clang/test/CodeGen/avr/avr-inline-asm-constraints.c 
b/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
index 96774861feb228..3a956de8db48f0 100644
--- a/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
+++ b/clang/test/CodeGen/avr/avr-inline-asm-constraints.c
@@ -109,8 +109,8 @@ void R() {
 }
 
 void G() {
-  // CHECK: call addrspace(0) void asm sideeffect "subi r30, $0", "G"(i16 50)
-  asm("subi r30, %0" :: "G"(50));
+  // CHECK: call addrspace(0) void asm sideeffect "subi r30, $0", "G"(i16 0)
+  asm("subi r30, %0" :: "G"(0));
 }
 
 void Q() {
diff --git a/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c 
b/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
index ceea59229f736a..29f0b69285fa88 100644
--- a/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
+++ b/clang/test/CodeGen/avr/avr-unsupported-inline-asm-constraints.c
@@ -5,4 +5,5 @@ const unsigned char val = 0;
 int foo(void) {
   __asm__ volatile("foo %0, 1" : : "fo" (val)); // expected-error {{invalid 
input constraint 'fo' in asm}}
   __asm__ volatile("foo %0, 1" : : "Nd" (val)); // expected-error {{invalid 
input constraint 'Nd' in asm}}
+  __asm__ volatile("subi r30, %0" : : "G" (1)); // expected-error {{value '1' 
out of range for constraint 'G'}}
 }

``




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


[llvm] [clang] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits

nikic wrote:

There are lld test failures.

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


[llvm] [clang] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits


@@ -27,7 +27,7 @@
 #endif
 
 // function return types
-// CHECK-LABEL: define dso_local <8 x half> @test_ret_v8f16(
+// CHECK-LABEL: define dso_local noundef <8 x half> @test_ret_v8f16(

nikic wrote:

Do you know why clang places the noundef on the argument but not the return for 
these, despite them having the same type?

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


[llvm] [clang] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits

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


[llvm] [clang] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits


@@ -27,7 +27,7 @@
 #endif
 
 // function return types
-// CHECK-LABEL: define dso_local <8 x half> @test_ret_v8f16(
+// CHECK-LABEL: define dso_local noundef <8 x half> @test_ret_v8f16(

nikic wrote:

Ah, it seems to indeed be a "weird C rule":
https://github.com/llvm/llvm-project/blob/3c92011b600bdf70424e2547594dd461fe411a41/clang/lib/CodeGen/CGCall.cpp#L1816-L1819

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


[llvm] [clang] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits


@@ -1279,6 +1280,43 @@ static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
   }
 }
 
+/// Deduce noundef attributes for the SCC.
+static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
+SmallSet &Changed) {
+  // Check each function in turn, determining which functions return noundef
+  // values.
+  for (Function *F : SCCNodes) {
+// Already noundef.
+if (F->getAttributes().hasRetAttr(Attribute::NoUndef))
+  continue;
+
+// We can infer and propagate function attributes only when we know that 
the
+// definition we'll get at link time is *exactly* the definition we see 
now.
+// For more details, see GlobalValue::mayBeDerefined.
+if (!F->hasExactDefinition())
+  return;
+
+if (F->getReturnType()->isVoidTy())
+  continue;
+
+bool HasAnyUndefs = false;
+for (BasicBlock &BB : *F)
+  if (auto *Ret = dyn_cast(BB.getTerminator())) {
+// TODO: performs context-sensitive analysis?
+if (!isGuaranteedNotToBeUndefOrPoison(Ret->getReturnValue())) {
+  HasAnyUndefs = true;
+  break;

nikic wrote:

Use `any_of` (or `none_of` or whatever is most convenient). 

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


[clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits


@@ -1279,6 +1280,43 @@ static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
   }
 }
 
+/// Deduce noundef attributes for the SCC.
+static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
+SmallSet &Changed) {
+  // Check each function in turn, determining which functions return noundef
+  // values.
+  for (Function *F : SCCNodes) {
+// Already noundef.
+if (F->getAttributes().hasRetAttr(Attribute::NoUndef))
+  continue;
+
+// We can infer and propagate function attributes only when we know that 
the
+// definition we'll get at link time is *exactly* the definition we see 
now.
+// For more details, see GlobalValue::mayBeDerefined.
+if (!F->hasExactDefinition())
+  return;
+
+if (F->getReturnType()->isVoidTy())
+  continue;
+
+bool HasAnyUndefs = false;
+for (BasicBlock &BB : *F)
+  if (auto *Ret = dyn_cast(BB.getTerminator())) {
+// TODO: performs context-sensitive analysis?

nikic wrote:

```suggestion
// TODO: perform context-sensitive analysis?
```

https://github.com/llvm/llvm-project/pull/76553
___
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 via cfe-commits

DonatNagyE wrote:

Thanks for updating the test names. I think it's safe to merge this now (as 
@steakhal also had an opportunity to look at it).

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][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'd like there to be some distinction between "modules not present because 
Clang was built without them" and "modules not present but expected to be 
there" (maybe distro packagers split things and the modules package is 
missing?).

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] [clang][modules] Print library module manifest path. (PR #76451)

2023-12-29 Thread Thorsten Schütt 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: ="

tschuett wrote:

If the output starts with a /, then it is the path. If the output starts with 
error:, then there will be some actionable information. 

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] [llvm] [clang-tools-extra] [analyzer] Trust base to derived casts for dynamic types (PR #69057)

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

https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/69057

>From 8ed4effd114ebd83d4ceaa37655ffd9b7105b28e Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Sat, 14 Oct 2023 15:51:42 +0200
Subject: [PATCH 1/5] [analyzer] Trust base to derived casts for dynamic types

When doing a base to derived cast, and we should add a cast info
recording that fact.
This information will be then used for example inside
`CXXInstanceCall::getRuntimeDefinition` (CallEvent.cpp), where for
virtual calls, it will query the associated dynamic type for the `*this` region.

Note that inside `ExprEngine::defaultEvalCall`, if the runtime
definition is found but it might have other definitions, then we will
split the path and have one where we inline the candidate and one other
doing conservative call evaluation. This ensures that if we inlined the
wrong definition, we still have a path where conservative evaluation happened.
In addition to this, remember that once a function was conservatively
evaluated on a path, then further calls to the same function will always
result in conservative evaluation, see `ExprEngine::BifurcateCall` and
the `DynamicDispatchBifurcationMap`.

As a consequence of these rules, we can have execution paths where a
function call might be resolved to different implemetations, depending
on the sequence of events, like here:

```C++
void top(Base *p) {
  p->fun(); // Will split into 2 paths:
  // 1) Inlines the virtual `Base::fun()`.
  // 2) Conservative eval calls, and remembers to always conservatively eval 
this function.

  // Perform a base to derived cast, and just discard the result.
  (void)static_cast(p);

  p->fun(); // Will split path (1) into 2:
  // 2.1) Inlines the virtual `Derived::fun()`.
  // 2.2) Conservative eval calls, and remembers to always conservatively eval 
this function.

  // Now, we have exactly 3 paths at this point.
}
```

Fixes #62663
---
 .../Checkers/DynamicTypePropagation.cpp   |  27 +++--
 .../Analysis/cast-trust-base-to-derived.cpp   | 105 ++
 .../test/Analysis/osobject-retain-release.cpp |  12 +-
 3 files changed, 129 insertions(+), 15 deletions(-)
 create mode 100644 clang/test/Analysis/cast-trust-base-to-derived.cpp

diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index eda8302595ba4f..6539f3c1e09e32 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -20,6 +20,7 @@
 //
 
//===--===//
 
+#include "clang/AST/OperationKinds.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/Builtins.h"
@@ -392,10 +393,6 @@ void DynamicTypePropagation::checkPostCall(const CallEvent 
&Call,
   }
 }
 
-/// TODO: Handle explicit casts.
-///   Handle C++ casts.
-///
-/// Precondition: the cast is between ObjCObjectPointers.
 ExplodedNode *DynamicTypePropagation::dynamicTypePropagationOnCasts(
 const CastExpr *CE, ProgramStateRef &State, CheckerContext &C) const {
   // We only track type info for regions.
@@ -403,8 +400,19 @@ ExplodedNode 
*DynamicTypePropagation::dynamicTypePropagationOnCasts(
   if (!ToR)
 return C.getPredecessor();
 
-  if (isa(CE))
+  if (CE->getCastKind() == CK_BaseToDerived) {
+bool CastSucceeds = true;
+QualType FromTy = CE->getSubExpr()->getType();
+QualType ToTy = CE->getType();
+ToR = ToR->StripCasts(/*StripBaseAndDerivedCasts=*/true);
+State = setDynamicTypeAndCastInfo(State, ToR, FromTy, ToTy, CastSucceeds);
+return C.addTransition(State);
+  }
+
+  // TODO: Handle the rest of explicit casts, inluding the regular C++ casts.
+  if (isa(CE)) {
 return C.getPredecessor();
+  }
 
   if (const Type *NewTy = getBetterObjCType(CE, C)) {
 State = setDynamicTypeInfo(State, ToR, QualType(NewTy, 0));
@@ -609,9 +617,13 @@ storeWhenMoreInformative(ProgramStateRef &State, SymbolRef 
Sym,
 /// symbol and the destination type of the cast are unrelated, report an error.
 void DynamicTypePropagation::checkPostStmt(const CastExpr *CE,
CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+  ExplodedNode *AfterTypeProp = dynamicTypePropagationOnCasts(CE, State, C);
+
   if (CE->getCastKind() != CK_BitCast)
 return;
 
+  ASTContext &ASTCtxt = C.getASTContext();
   QualType OriginType = CE->getSubExpr()->getType();
   QualType DestType = CE->getType();
 
@@ -621,11 +633,6 @@ void DynamicTypePropagation::checkPostStmt(const CastExpr 
*CE,
   if (!OrigObjectPtrType || !DestObjectPtrType)
 return;
 
-  ProgramStateRef State = C.getState();
-  ExplodedNode *AfterTypeProp = dynamicTypePropagationOnCasts(CE, State, C);
-
-  ASTContext &ASTCtxt = C.getASTContext();
-
   // This checker detects the subtyping relationships using the assignment

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

2023-12-29 Thread via cfe-commits

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

>From 24aa5e41505eebb64288e7369a3b4f35ee0214fc Mon Sep 17 00:00:00 2001
From: XDeme 
Date: Sun, 24 Dec 2023 11:27:31 -0300
Subject: [PATCH 1/2] [clang-format] Fix bad indentation with attribute and
 templated type

---
 clang/lib/Format/ContinuationIndenter.cpp | 2 +-
 clang/unittests/Format/FormatTest.cpp | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

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..d5265aa230c7d2 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26492,6 +26492,10 @@ TEST_F(FormatTest, BreakAfterAttributes) {
   verifyFormat("[[nodiscard]]\n"
"Foo& operator-(Foo&);",
Style);
+
+  verifyFormat("[[maybe_unused]]\n"
+   "foo f;",
+   Style);
 }
 
 TEST_F(FormatTest, InsertNewlineAtEOF) {

>From d049c7f8169d1766363638b50365d8562bc6df7d Mon Sep 17 00:00:00 2001
From: XDeme 
Date: Fri, 29 Dec 2023 11:48:47 -0300
Subject: [PATCH 2/2] Addresses comments

---
 clang/unittests/Format/FormatTest.cpp | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index d5265aa230c7d2..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"
@@ -26492,10 +26497,6 @@ TEST_F(FormatTest, BreakAfterAttributes) {
   verifyFormat("[[nodiscard]]\n"
"Foo& operator-(Foo&);",
Style);
-
-  verifyFormat("[[maybe_unused]]\n"
-   "foo f;",
-   Style);
 }
 
 TEST_F(FormatTest, InsertNewlineAtEOF) {

___
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

steakhal wrote:

> Thanks for the replies. I'll come back to this PR once I have some time; 
> maybe during the holidays. Both assertions directly relate to this PR for 
> sure.

I think I've just fixed the reported crash for this PR. For some reason a 
`CastExpr` does not have a reference type (`getType()`), even though it casts 
lvalue expressions - in case casting references instead of pointers). I have no 
clue why that's the case, but the workaround seems to work now. Added a 
testcase demonstrating the fix.

---

> Hm, testing these patches on the original testcase in #62663 (the one where 
> we use statements 1B and 2B) - I don't think this patchset solves that 
> scenario...

I've looked into the case and I think now I see your problem.

In case we have `2B` instead of `2A`, we no longer have a cast to hint us the 
dynamic type of the object; consequently we can't follow/devirtualize the call. 
So, we are basically forced to conservatively evaluate the call, as if the body 
is not present.
This is strictly speaking correct, but also not particularly useful.

If I'm not mistaken, inheritance has "open-set" semantics, which means that in 
our current translation-unit we might not see all the derived classes, and 
could be that some derived classes are loaded only at runtime using shared 
libraries fox example.

What it means for us is that, by seeing a `Base*`, which has a pure virtual 
function, and that only a single class inherits transitively from `Base` (and 
defines the virtual function); we can't be really sure that by calling that 
virtual function it will invoke that particular function.

For example, in an other translation unit they might define a `NewDerived` 
implementing `Base` slightly differently and smuggle a  pointer into our 
context; breaking local reasoning. Which means that the call to 
`foo->OnRecvCancel(port)` could potentially invoke a completely different 
definition that we saw in our translation unit.

If we would have seen the allocation (thus the dynamic type) of the object of 
which we call functions, it's fairly easy to inline the right definitions. 
However, when we need to guess what could be the dynamic type, its no longer 
that easy.

In presence of static-casts, the developer at least hinted a type, so in that 
case we have some justification for trusting the type there; otherwise all bets 
are off.

---

What could we do about inlining function definitions without knowing precisely 
the dynamic type of the object?

I think it would still make sense to assume well architected code and if only 
one thing derives (implements) a Base class, then it's probably safe to assume 
that that's the definition we want to inline. However, what should we do if 
multiple (N) classes implement Base? Trying each N, and basically splitting the 
state to (N+1) ways is not going to scale. Unless N is of course really small, 
like 2 or 3 at most.

To conclude, I don't think we could get the `2B` case working (by inlining the 
`Handler::OnRecvCancel(int)`); but I'll think about it.
Maybe you have some thoughts @Xazax-hun.

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-format] Fix bad indentation with attribute and templated type (PR #76336)

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

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


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] [clang][Sema] Add diagnostics for out-of-bounds vector access (PR #76569)

2023-12-29 Thread via cfe-commits

https://github.com/implicitfield created 
https://github.com/llvm/llvm-project/pull/76569

Fixes #76490

>From 5b95122ede9373bb031061ead75140b9f27bad29 Mon Sep 17 00:00:00 2001
From: implicitfield <114500360+implicitfi...@users.noreply.github.com>
Date: Fri, 29 Dec 2023 01:52:49 +0400
Subject: [PATCH] [clang][Sema] Add diagnostics for out-of-bounds vector access

Fixes #76490
---
 .../clang/Basic/DiagnosticSemaKinds.td|  8 
 clang/lib/Sema/SemaChecking.cpp   | 39 +++
 clang/test/Sema/array-bounds-vector.c | 10 +
 3 files changed, 57 insertions(+)
 create mode 100644 clang/test/Sema/array-bounds-vector.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aebb7d9b945c33..4ab03f0d9518fd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9689,6 +9689,12 @@ def warn_array_index_precedes_bounds : Warning<
 def warn_array_index_exceeds_bounds : Warning<
   "array index %0 is past the end of the array (that has type %1%select{|, 
cast to %3}2)">,
   InGroup;
+def warn_vector_index_precedes_bounds : Warning<
+  "vector index %0 is before the beginning of the vector">,
+  InGroup;
+def warn_vector_index_exceeds_bounds : Warning<
+  "vector index %0 is past the end of the vector (that has type %1)">,
+  InGroup;
 def warn_ptr_arith_exceeds_max_addressable_bounds : Warning<
   "the pointer incremented by %0 refers past the last possible element for an 
array in %1-bit "
   "address space containing %2-bit (%3-byte) elements (max possible %4 
element%s5)">,
@@ -9699,6 +9705,8 @@ def warn_array_index_exceeds_max_addressable_bounds : 
Warning<
   InGroup;
 def note_array_declared_here : Note<
   "array %0 declared here">;
+def note_vector_declared_here : Note<
+  "vector %0 declared here">;
 
 def warn_inconsistent_array_form : Warning<
   "argument %0 of type %1 with mismatched bound">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index da0570b7b0f1e6..3a52b84e331b85 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17914,6 +17914,45 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, 
const Expr *IndexExpr,
 index = -index;
   }
 
+  if (EffectiveType->isVectorType()) {
+if (AllowOnePastEnd) {
+  // Pointer arithmetic on vectors isn't legal, so let's not emit a
+  // diagnostic since we'll produce an error later anyway.
+  return;
+}
+
+if (index.isUnsigned() || !index.isNegative()) {
+  const auto *VT = EffectiveType->castAs();
+  if (index.ult(VT->getNumElements()))
+return;
+
+  DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+  PDiag(diag::warn_vector_index_exceeds_bounds)
+  << toString(index, 10, true) << VT->desugar()
+  << IndexExpr->getSourceRange());
+} else {
+  DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+  PDiag(diag::warn_vector_index_precedes_bounds)
+  << toString(index, 10, true)
+  << IndexExpr->getSourceRange());
+}
+
+const NamedDecl *ND = nullptr;
+// Try harder to find a NamedDecl to point at in the note.
+while (const auto *ASE = dyn_cast(BaseExpr))
+  BaseExpr = ASE->getBase()->IgnoreParenCasts();
+if (const auto *DRE = dyn_cast(BaseExpr))
+  ND = DRE->getDecl();
+if (const auto *ME = dyn_cast(BaseExpr))
+  ND = ME->getMemberDecl();
+
+if (ND)
+  DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,
+  PDiag(diag::note_vector_declared_here) << ND);
+
+return;
+  }
+
   if (IsUnboundedArray) {
 if (EffectiveType->isFunctionType())
   return;
diff --git a/clang/test/Sema/array-bounds-vector.c 
b/clang/test/Sema/array-bounds-vector.c
new file mode 100644
index 00..e5a940a7d17864
--- /dev/null
+++ b/clang/test/Sema/array-bounds-vector.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Warray-bounds -verify %s
+
+typedef double float64x1_t __attribute__ ((__vector_size__ (sizeof (double;
+void foo(double i)
+{
+float64x1_t j = {i}; // expected-note 2 {{vector 'j' declared here}}
+double U = j[0];
+double V = j[1]; // expected-warning {{vector index 1 is past the end of 
the vector (that has type '__attribute__((__vector_size__(1 * sizeof(double 
double' (vector of 1 'double' value))}}
+double W = j[-1]; // expected-warning {{vector index -1 is before the 
beginning of the vector}}
+}

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


[clang] [clang][Sema] Add diagnostics for out-of-bounds vector access (PR #76569)

2023-12-29 Thread via cfe-commits

github-actions[bot] wrote:

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

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

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

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

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

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

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

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


[clang] [clang][Sema] Add diagnostics for out-of-bounds vector access (PR #76569)

2023-12-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (implicitfield)


Changes

Fixes #76490

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


3 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+8) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+39) 
- (added) clang/test/Sema/array-bounds-vector.c (+10) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aebb7d9b945c33..4ab03f0d9518fd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9689,6 +9689,12 @@ def warn_array_index_precedes_bounds : Warning<
 def warn_array_index_exceeds_bounds : Warning<
   "array index %0 is past the end of the array (that has type %1%select{|, 
cast to %3}2)">,
   InGroup;
+def warn_vector_index_precedes_bounds : Warning<
+  "vector index %0 is before the beginning of the vector">,
+  InGroup;
+def warn_vector_index_exceeds_bounds : Warning<
+  "vector index %0 is past the end of the vector (that has type %1)">,
+  InGroup;
 def warn_ptr_arith_exceeds_max_addressable_bounds : Warning<
   "the pointer incremented by %0 refers past the last possible element for an 
array in %1-bit "
   "address space containing %2-bit (%3-byte) elements (max possible %4 
element%s5)">,
@@ -9699,6 +9705,8 @@ def warn_array_index_exceeds_max_addressable_bounds : 
Warning<
   InGroup;
 def note_array_declared_here : Note<
   "array %0 declared here">;
+def note_vector_declared_here : Note<
+  "vector %0 declared here">;
 
 def warn_inconsistent_array_form : Warning<
   "argument %0 of type %1 with mismatched bound">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index da0570b7b0f1e6..3a52b84e331b85 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17914,6 +17914,45 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, 
const Expr *IndexExpr,
 index = -index;
   }
 
+  if (EffectiveType->isVectorType()) {
+if (AllowOnePastEnd) {
+  // Pointer arithmetic on vectors isn't legal, so let's not emit a
+  // diagnostic since we'll produce an error later anyway.
+  return;
+}
+
+if (index.isUnsigned() || !index.isNegative()) {
+  const auto *VT = EffectiveType->castAs();
+  if (index.ult(VT->getNumElements()))
+return;
+
+  DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+  PDiag(diag::warn_vector_index_exceeds_bounds)
+  << toString(index, 10, true) << VT->desugar()
+  << IndexExpr->getSourceRange());
+} else {
+  DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+  PDiag(diag::warn_vector_index_precedes_bounds)
+  << toString(index, 10, true)
+  << IndexExpr->getSourceRange());
+}
+
+const NamedDecl *ND = nullptr;
+// Try harder to find a NamedDecl to point at in the note.
+while (const auto *ASE = dyn_cast(BaseExpr))
+  BaseExpr = ASE->getBase()->IgnoreParenCasts();
+if (const auto *DRE = dyn_cast(BaseExpr))
+  ND = DRE->getDecl();
+if (const auto *ME = dyn_cast(BaseExpr))
+  ND = ME->getMemberDecl();
+
+if (ND)
+  DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,
+  PDiag(diag::note_vector_declared_here) << ND);
+
+return;
+  }
+
   if (IsUnboundedArray) {
 if (EffectiveType->isFunctionType())
   return;
diff --git a/clang/test/Sema/array-bounds-vector.c 
b/clang/test/Sema/array-bounds-vector.c
new file mode 100644
index 00..e5a940a7d17864
--- /dev/null
+++ b/clang/test/Sema/array-bounds-vector.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Warray-bounds -verify %s
+
+typedef double float64x1_t __attribute__ ((__vector_size__ (sizeof (double;
+void foo(double i)
+{
+float64x1_t j = {i}; // expected-note 2 {{vector 'j' declared here}}
+double U = j[0];
+double V = j[1]; // expected-warning {{vector index 1 is past the end of 
the vector (that has type '__attribute__((__vector_size__(1 * sizeof(double 
double' (vector of 1 'double' value))}}
+double W = j[-1]; // expected-warning {{vector index -1 is before the 
beginning of the vector}}
+}

``




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


[clang] [OpenMP] Introduce -fopenmp-force-usm flag (PR #75468)

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

https://github.com/jplehr updated 
https://github.com/llvm/llvm-project/pull/75468

>From 8f381c760fca8a4abd7550c492ff22fa8972933a Mon Sep 17 00:00:00 2001
From: JP Lehr 
Date: Thu, 6 Jul 2023 16:47:21 -0400
Subject: [PATCH 1/3] [OpenMP] Introduce -fopenmp-force-usm flag

The new flag implements logic to include #pragma omp requires
unified_shared_memory in every translation unit.
This enables a straightforward way to enable USM for an application
without the need to modify sources.
---
 clang/include/clang/Driver/Options.td|  2 ++
 clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp | 16 
 clang/lib/Headers/CMakeLists.txt |  1 +
 .../lib/Headers/openmp_wrappers/usm/force_usm.h  |  6 ++
 4 files changed, 25 insertions(+)
 create mode 100644 clang/lib/Headers/openmp_wrappers/usm/force_usm.h

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 2b93ddf033499c..e33bc7d1b10d71 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3381,6 +3381,8 @@ def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], 
"fopenmp-cuda-blocks-per-sm=">
   Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
 def fopenmp_cuda_teams_reduction_recs_num_EQ : Joined<["-"], 
"fopenmp-cuda-teams-reduction-recs-num=">, Group,
   Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group,
+  Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
 
 
//===--===//
 // Shared cc1 + fc1 OpenMP Target Options
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp 
b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index b012b7cb729378..a077f2f06d7728 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -129,6 +129,22 @@ AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList 
&Args) const {
 void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
   HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+
+  CC1Args.push_back("-internal-isystem");
+  SmallString<128> P(HostTC.getDriver().ResourceDir);
+  llvm::sys::path::append(P, "include/cuda_wrappers");
+  CC1Args.push_back(DriverArgs.MakeArgString(P));
+
+  // Force USM mode will forcefully include #pragma omp requires
+  // unified_shared_memory via the force_usm header
+  // XXX This may result in a compilation error if the source
+  // file already includes that pragma.
+  if (DriverArgs.hasArg(options::OPT_fopenmp_force_usm)) {
+CC1Args.push_back("-include");
+CC1Args.push_back(
+DriverArgs.MakeArgString(HostTC.getDriver().ResourceDir +
+ "/include/openmp_wrappers/force_usm.h"));
+  }
 }
 
 void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 735e4e4e3be89b..ed491779abcd00 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -320,6 +320,7 @@ set(openmp_wrapper_files
   openmp_wrappers/__clang_openmp_device_functions.h
   openmp_wrappers/complex_cmath.h
   openmp_wrappers/new
+  openmp_wrappers/usm/force_usm.h
 )
 
 set(llvm_libc_wrapper_files
diff --git a/clang/lib/Headers/openmp_wrappers/usm/force_usm.h 
b/clang/lib/Headers/openmp_wrappers/usm/force_usm.h
new file mode 100644
index 00..15c394e27ce9c2
--- /dev/null
+++ b/clang/lib/Headers/openmp_wrappers/usm/force_usm.h
@@ -0,0 +1,6 @@
+#ifndef __CLANG_FORCE_OPENMP_USM
+#define __CLANG_FORCE_OPENMP_USM
+
+#pragma omp requires unified_shared_memory
+
+#endif

>From 4d5a1f670b3bdd5b183515e347610414cb12cb90 Mon Sep 17 00:00:00 2001
From: JP Lehr 
Date: Fri, 29 Dec 2023 04:33:19 -0500
Subject: [PATCH 2/3] Revert "[OpenMP] Introduce -fopenmp-force-usm flag"

This reverts commit 4ecd07d786a5a994b33b9177d4e21d839bfe3fc9.

To test the other solution.
---
 clang/include/clang/Driver/Options.td|  2 --
 clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp | 16 
 clang/lib/Headers/CMakeLists.txt |  1 -
 .../lib/Headers/openmp_wrappers/usm/force_usm.h  |  6 --
 4 files changed, 25 deletions(-)
 delete mode 100644 clang/lib/Headers/openmp_wrappers/usm/force_usm.h

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index e33bc7d1b10d71..2b93ddf033499c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3381,8 +3381,6 @@ def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], 
"fopenmp-cuda-blocks-per-sm=">
   Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
 def fopenmp_cuda_teams_reduction_recs_num_EQ : Joined<["-"], 
"fopenmp-cuda-teams-reduction-recs-num=">, Group

[clang] [OpenMP][USM] Adds test for -fopenmp-force-usm flag (PR #75467)

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

jplehr wrote:

I updated the feature PR (#75468) with a different solution. Will update the 
test after feedback if the route I took in the other PR is seen as OK.

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


[clang] [OpenMP] Introduce -fopenmp-force-usm flag (PR #75468)

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 3c92011b600bdf70424e2547594dd461fe411a41 
f0aaefbe923d2daa1752f3a9664dab3958346c51 -- 
clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/Driver/ToolChains/Clang.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 09204c3017..4855e7410a 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1045,7 +1045,8 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
  : StringRef{});
   OMPBuilder.setConfig(Config);
 
-  // The user forces the compiler to behave as if omp requires 
unified_shared_memory was given.
+  // The user forces the compiler to behave as if omp requires
+  // unified_shared_memory was given.
   if (CGM.getLangOpts().OpenMPForceUSM) {
 HasRequiresUnifiedSharedMemory = true;
 OMPBuilder.Config.setHasRequiresUnifiedSharedMemory(true);

``




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


[clang] [OpenMP] Introduce -fopenmp-force-usm flag (PR #75468)

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

jplehr wrote:

Hmm.. I guess I screwed something up with git and the history.

https://github.com/llvm/llvm-project/pull/75468
___
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

https://github.com/jplehr created 
https://github.com/llvm/llvm-project/pull/76571

This flag forces the compiler to generate code for OpenMP target regions as if 
the user specified the #pragma omp requires unified_shared_memory in each 
source file.

The option does not have a -fno-* friend since OpenMP requires the 
unified_shared_memory clause to be present in all source files. Since this flag 
does no harm if the clause is present, it can be used in conjunction. My 
understanding is that USM should not be turned off selectively, hence, no -fno- 
version.

In favor of https://github.com/llvm/llvm-project/pull/75468, sorry for the 
noise and confusion.

>From bf25a538e7c020efde557b595eba64b804cbb817 Mon Sep 17 00:00:00 2001
From: JP Lehr 
Date: Fri, 29 Dec 2023 04:32:24 -0500
Subject: [PATCH] [OpenMP][USM] Introduces -fopenmp-force-usm flag

This flag forces the compiler to generate code for OpenMP target regions
as if the user specified the #pragma omp requires unified_shared_memory
in each source file.

The option does not have a -fno-* friend since OpenMP requires the
unified_shared_memory clause to be present in all source files. Since
this flag does no harm if the clause is present, it can be used in
conjunction. My understanding is that USM should not be turned off
selectively, hence, no -fno- version.
---
 clang/include/clang/Basic/LangOptions.def | 1 +
 clang/include/clang/Driver/Options.td | 4 
 clang/lib/CodeGen/CGOpenMPRuntime.cpp | 7 +++
 clang/lib/Driver/ToolChains/Clang.cpp | 2 ++
 4 files changed, 14 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 21abc346cf17ac..81cf2ad9498a7f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -260,6 +260,7 @@ LANGOPT(OpenMPTeamSubscription  , 1, 0, "Assume distributed 
loops do not have mo
 LANGOPT(OpenMPNoThreadState  , 1, 0, "Assume that no thread in a parallel 
region will modify an ICV.")
 LANGOPT(OpenMPNoNestedParallelism  , 1, 0, "Assume that no thread in a 
parallel region will encounter a parallel region")
 LANGOPT(OpenMPOffloadMandatory  , 1, 0, "Assert that offloading is mandatory 
and do not create a host fallback.")
+LANGOPT(OpenMPForceUSM , 1, 0, "Enable OpenMP unified shared memory mode 
via compiler.")
 LANGOPT(NoGPULib  , 1, 0, "Indicate a build without the standard GPU 
libraries.")
 LANGOPT(RenderScript  , 1, 0, "RenderScript")
 
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 2b93ddf033499c..28290da438c62d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3451,6 +3451,10 @@ def fopenmp_offload_mandatory : Flag<["-"], 
"fopenmp-offload-mandatory">, Group<
   Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
   HelpText<"Do not create a host fallback if offloading to the device fails.">,
   MarshallingInfoFlag>;
+def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group,
+  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Force behvaior as if the user specified pragma omp requires 
unified_shared_memory.">,
+  MarshallingInfoFlag>;
 def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group,
   Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption]>,
   HelpText<"Emit code that can be JIT compiled for OpenMP offloading. Implies 
-foffload-lto=full">;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index ea6645a39e8321..4855e7410a015a 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1044,6 +1044,13 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
  ? CGM.getLangOpts().OMPHostIRFile
  : StringRef{});
   OMPBuilder.setConfig(Config);
+
+  // The user forces the compiler to behave as if omp requires
+  // unified_shared_memory was given.
+  if (CGM.getLangOpts().OpenMPForceUSM) {
+HasRequiresUnifiedSharedMemory = true;
+OMPBuilder.Config.setHasRequiresUnifiedSharedMemory(true);
+  }
 }
 
 void CGOpenMPRuntime::clear() {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index acfa119805068d..ffc24201ab2e0b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6382,6 +6382,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
 CmdArgs.push_back("-fopenmp-assume-no-nested-parallelism");
   if (Args.hasArg(options::OPT_fopenmp_offload_mandatory))
 CmdArgs.push_back("-fopenmp-offload-mandatory");
+  if (Args.hasArg(options::OPT_fopenmp_force_usm))
+CmdArgs.push_back("-fopenmp-force-usm");
   break;
 default:
   // By default, if Clang doesn't know how to generate useful OpenMP code

_

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

2023-12-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Jan Patrick Lehr (jplehr)


Changes

This flag forces the compiler to generate code for OpenMP target regions as if 
the user specified the #pragma omp requires unified_shared_memory in each 
source file.

The option does not have a -fno-* friend since OpenMP requires the 
unified_shared_memory clause to be present in all source files. Since this flag 
does no harm if the clause is present, it can be used in conjunction. My 
understanding is that USM should not be turned off selectively, hence, no -fno- 
version.

In favor of https://github.com/llvm/llvm-project/pull/75468, sorry for the 
noise and confusion.

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


4 Files Affected:

- (modified) clang/include/clang/Basic/LangOptions.def (+1) 
- (modified) clang/include/clang/Driver/Options.td (+4) 
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+7) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+2) 


``diff
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 21abc346cf17ac..81cf2ad9498a7f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -260,6 +260,7 @@ LANGOPT(OpenMPTeamSubscription  , 1, 0, "Assume distributed 
loops do not have mo
 LANGOPT(OpenMPNoThreadState  , 1, 0, "Assume that no thread in a parallel 
region will modify an ICV.")
 LANGOPT(OpenMPNoNestedParallelism  , 1, 0, "Assume that no thread in a 
parallel region will encounter a parallel region")
 LANGOPT(OpenMPOffloadMandatory  , 1, 0, "Assert that offloading is mandatory 
and do not create a host fallback.")
+LANGOPT(OpenMPForceUSM , 1, 0, "Enable OpenMP unified shared memory mode 
via compiler.")
 LANGOPT(NoGPULib  , 1, 0, "Indicate a build without the standard GPU 
libraries.")
 LANGOPT(RenderScript  , 1, 0, "RenderScript")
 
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 2b93ddf033499c..28290da438c62d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3451,6 +3451,10 @@ def fopenmp_offload_mandatory : Flag<["-"], 
"fopenmp-offload-mandatory">, Group<
   Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
   HelpText<"Do not create a host fallback if offloading to the device fails.">,
   MarshallingInfoFlag>;
+def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group,
+  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Force behvaior as if the user specified pragma omp requires 
unified_shared_memory.">,
+  MarshallingInfoFlag>;
 def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group,
   Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption]>,
   HelpText<"Emit code that can be JIT compiled for OpenMP offloading. Implies 
-foffload-lto=full">;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index ea6645a39e8321..4855e7410a015a 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1044,6 +1044,13 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
  ? CGM.getLangOpts().OMPHostIRFile
  : StringRef{});
   OMPBuilder.setConfig(Config);
+
+  // The user forces the compiler to behave as if omp requires
+  // unified_shared_memory was given.
+  if (CGM.getLangOpts().OpenMPForceUSM) {
+HasRequiresUnifiedSharedMemory = true;
+OMPBuilder.Config.setHasRequiresUnifiedSharedMemory(true);
+  }
 }
 
 void CGOpenMPRuntime::clear() {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index acfa119805068d..ffc24201ab2e0b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6382,6 +6382,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
 CmdArgs.push_back("-fopenmp-assume-no-nested-parallelism");
   if (Args.hasArg(options::OPT_fopenmp_offload_mandatory))
 CmdArgs.push_back("-fopenmp-offload-mandatory");
+  if (Args.hasArg(options::OPT_fopenmp_force_usm))
+CmdArgs.push_back("-fopenmp-force-usm");
   break;
 default:
   // By default, if Clang doesn't know how to generate useful OpenMP code

``




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] [clang][modules] Print library module manifest path. (PR #76451)

2023-12-29 Thread Mark de Wever 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: ="

mordante wrote:

> I'd like there to be some distinction between "modules not present because 
> Clang was built without them" and "modules not present but expected to be 
> there" (maybe distro packagers split things and the modules package is 
> missing?).

However that is hard to do and might be wrong. Currently stdlibc++ does not 
ship modules. I don't know how clang-18 will ever find them stdlibc++-15 since 
it's unknown whether that version will have modules nor do I know the name of 
their manifest file.

Same for Clang and libc++,  Clang has no idea whether libc++ was build with or 
without modules. They are build independently. So it would need to look at the 
version information of libc++ to detect whether it's libc++-18 or earlier. 
Earlier never has the manifest.

IMO tool vendors should look at the output of this command; it either contains 
a path or a single error value. If it's the error value they should not attempt 
to build the std module.

What would be the benefit of different errors @mathstuf ? Especially 
considering the above that it's hard to determine the proper error message.

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] [OpenMP] Introduce -fopenmp-force-usm flag (PR #75468)

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

https://github.com/jplehr closed https://github.com/llvm/llvm-project/pull/75468
___
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


[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] [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

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?
> 
> 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] [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] [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] [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][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 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 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 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 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 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


[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] [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"

[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] [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-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][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] [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

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


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


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

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 
{
+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


@@ -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"};

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);
+  }
+
+  // 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"};
+
+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] [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] 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

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] [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


[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-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 

[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] [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][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


@@ -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] [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"};
+
+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 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)

[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-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


[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


[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


[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


[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 `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] [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 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 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


  1   2   >