[clang] [analyzer] Fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits

steakhal wrote:

Backporting to clang-19 in https://github.com/llvm/llvm-project/pull/101684

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


[clang] [analyzer] Fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Restore recognition of mutex methods (PR #101511)

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


steakhal wrote:

Backport PR in https://github.com/llvm/llvm-project/pull/101651

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


[clang] [analyzer] Restore recognition of mutex methods (PR #101511)

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


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


[clang] [analyzer] Restore recognition of mutex methods (PR #101511)

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


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

Let's merge this, and backport it into clang-19. I'll deal with that.

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


[clang] [clang][Static analyzer] fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits


@@ -472,7 +472,19 @@ SVal StoreManager::getLValueElement(QualType elementType, 
NonLoc Offset,
   const auto *ElemR = dyn_cast(BaseRegion);
 
   // Convert the offset to the appropriate size and signedness.
-  Offset = svalBuilder.convertToArrayIndex(Offset).castAs();
+  auto Off = svalBuilder.convertToArrayIndex(Offset).getAs();
+  if (!Off) {
+// Handle cases when LazyCompoundVal is used for an array index.
+// Such case is possible if code does:
+//
+//   char b[4];
+//   a[__builtin_bitcast(int, b)];
+//

steakhal wrote:

```suggestion
//   char b[4];
//   a[__builtin_bitcast(int, b)];
```

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


[clang] [clang][Static analyzer] fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits


@@ -472,7 +472,19 @@ SVal StoreManager::getLValueElement(QualType elementType, 
NonLoc Offset,
   const auto *ElemR = dyn_cast(BaseRegion);
 
   // Convert the offset to the appropriate size and signedness.
-  Offset = svalBuilder.convertToArrayIndex(Offset).castAs();
+  auto Off = svalBuilder.convertToArrayIndex(Offset).getAs();

steakhal wrote:

```suggestion
  Offset = 
svalBuilder.convertToArrayIndex(Offset).getAs().value_or(UnknownVal());
```

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


[clang] [clang][Static analyzer] fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits


@@ -30,3 +30,10 @@ void f3(void *dest) {
   void *src = __builtin_alloca(5);
   memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a 
pointer to uninitialized value}}
 }
+
+// Reproduce crash from GH#94496. When array is used as subcript to another 
array, CSA cannot model it
+// and should just assume it's unknown and do not crash.
+void f4(char *array) {
+  char b[4] = {0};
+  array[__builtin_bit_cast(int, b)] = 0x10; // no crash

steakhal wrote:

Please enable the `debug.ExprInspection` checker too, and then forward declare 
(but not define) the `void clang_analyzer_dump_int(int);

```suggestion
  clang_analyzer_dump_int(__builtin_bit_cast(int, b)); // expected-warning 
{{Unknown}}
  array[__builtin_bit_cast(int, b)] = 0x10; // no crash
```

Hold on. Shouldn't we pin the target triple to be able to safely assume that a 
sizeof `int` is 4 chars? Consider pinning the target using `-triple xxx` in the 
RUN line.

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


[clang] [clang][Static analyzer] fix crash on using `bitcast(, )` as array subscript (PR #101647)

2024-08-02 Thread Balazs Benics via cfe-commits

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


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


[clang] [analyzer] Assert Callee is FunctionDecl in doesFnIntendToHandleOwnership() (PR #101066)

2024-08-01 Thread Balazs Benics via cfe-commits

steakhal wrote:

> > Already under fix in #100719, I'm just a lazy bum and haven't fixed the 
> > buildbots. I'll try to speed things up!
> 
> @Szelethus, would it possible to speed up the PR#100719? Thanks

Why?

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


[clang] [NFCI][clang][analyzer] Make ProgramStatePartialTrait a template definition (PR #98150)

2024-07-31 Thread Balazs Benics via cfe-commits

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


[clang] [Clang] add support for handling assume attributes (PR #101063)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

No, its cool. You are on the right track. Ill come back to you tomorrow.

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -923,12 +923,31 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const {
   return UnknownVal();
 }
 
+static bool isWithinStdNamespace(const Decl *D) {

steakhal wrote:

AFAIK not quite. Mine works even if the class a nested subclass within the std 
namespace, such as "std::vector::iterator". So directly using 
`isInStdNamespace` wouldn't quite cut it.

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-29 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -923,12 +923,31 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const {
   return UnknownVal();
 }
 
+static bool isWithinStdNamespace(const Decl *D) {

steakhal wrote:

@AaronBallman Do you think we clang already has something like this? Or it 
would make sense to have this part of Decl?

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

> This looks good now, documentation could be a bit more exact in that 
> operations on standard streams are not checked by the checker, like any other 
> operation on streams that are not opened on the analysis path.

Elaborated the docs section.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

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

>From 12ff3274fce8dfe534e71abb9511d6549e32f74c Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:33:55 +0200
Subject: [PATCH 1/7] [analyzer] Fix crash of StreamChecker when eval calling
 'fopen'

Actually, on the failure branch of `fopen`, the resulting pointer could
alias with `stdout` iff `stdout` is already known to be null.
We crashed in this case as the implementation assumed that the
state-split for creating the success and failure branches both should be
viable; thus dereferenced both of those states - leading to the crash.

To fix this, let's just only add this no-alias property for the success
path, and that's it :)

Fixes #100901
---
 clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp |  3 ++-
 clang/test/Analysis/stream.c| 10 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 53770532609d5..942e7541a83cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -938,7 +938,6 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
-  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -951,6 +950,8 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   StateNull =
   StateNull->set(RetSym, StreamState::getOpenFailed(Desc));
 
+  StateNotNull = assumeNoAliasingWithStdStreams(StateNotNull, RetVal, C);
+
   C.addTransition(StateNotNull,
   constructLeakNoteTag(C, RetSym, "Stream opened here"));
   C.addTransition(StateNull);
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index b3a47ce4153d3..575b32d97be31 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -502,11 +502,19 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
 extern FILE *stdout_like_ptr;
 void no_aliasing(void) {
   FILE *f = fopen("file", "r");
+  if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
-  if (f && f != stdout) {
+  if (f != stdout) {
 fclose(f);
   }
 } // no-leak: 'fclose()' is always called because 'f' cannot be 'stdout'.
+
+void only_success_path_does_not_alias_with_stdout(void) {
+  if (stdout) return;
+  FILE *f = fopen("/tmp/foof", "r"); // no-crash
+  if (!f) return;
+  fclose(f);
+}

>From 7453968ac1764adbc70f867d43fa3d63473b09f3 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:39:03 +0200
Subject: [PATCH 2/7] NFC Fixup previous PR comment

Addresses:
https://github.com/llvm/llvm-project/pull/100085#discussion_r1688051166
---
 clang/test/Analysis/stream.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index 575b32d97be31..aff884f190c8e 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -499,14 +499,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fclose(f);
 }
 
-extern FILE *stdout_like_ptr;
-void no_aliasing(void) {
+extern FILE *non_standard_stream_ptr;
+void test_fopen_does_not_alias_with_standard_streams(void) {
   FILE *f = fopen("file", "r");
   if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
-  clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
+  clang_analyzer_eval(f == non_standard_stream_ptr); // expected-warning 
{{FALSE}} expected-warning {{TRUE}}
   if (f != stdout) {
 fclose(f);
   }

>From db92245ab09f195cbb859d85f2b93a81fd1b2617 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:46:16 +0200
Subject: [PATCH 3/7] NFC Fixup previous PR comment

Addresses
https://github.com/llvm/llvm-project/pull/100085#discussion_r1688054004
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 25 ++-
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 942e7541a83cd..4454f30630e27 100644
--- 

[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -1766,13 +1770,6 @@ are assumed to succeed.)
fclose(p);
  }
 
-**Limitations**
-
-The checker does not track the correspondence between integer file descriptors
-and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
-treated specially and are therefore often not recognized (because these streams
-are usually not opened explicitly by the program, and are global variables).

steakhal wrote:

Ah indeed. So basically opening a file with file descriptor "ints" and then 
using `fdopen()` to get the corresponding `FILE *` - and back with `fileno()`. 
Yea, that seems weird to do :D Probably has its use somewhere though.
Anyways, makes sense now.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

@balazske Could you please have a look? I wanna make sure everyone is aligned.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

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

>From 12ff3274fce8dfe534e71abb9511d6549e32f74c Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:33:55 +0200
Subject: [PATCH 1/6] [analyzer] Fix crash of StreamChecker when eval calling
 'fopen'

Actually, on the failure branch of `fopen`, the resulting pointer could
alias with `stdout` iff `stdout` is already known to be null.
We crashed in this case as the implementation assumed that the
state-split for creating the success and failure branches both should be
viable; thus dereferenced both of those states - leading to the crash.

To fix this, let's just only add this no-alias property for the success
path, and that's it :)

Fixes #100901
---
 clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp |  3 ++-
 clang/test/Analysis/stream.c| 10 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 53770532609d5..942e7541a83cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -938,7 +938,6 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
-  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -951,6 +950,8 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   StateNull =
   StateNull->set(RetSym, StreamState::getOpenFailed(Desc));
 
+  StateNotNull = assumeNoAliasingWithStdStreams(StateNotNull, RetVal, C);
+
   C.addTransition(StateNotNull,
   constructLeakNoteTag(C, RetSym, "Stream opened here"));
   C.addTransition(StateNull);
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index b3a47ce4153d3..575b32d97be31 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -502,11 +502,19 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
 extern FILE *stdout_like_ptr;
 void no_aliasing(void) {
   FILE *f = fopen("file", "r");
+  if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
-  if (f && f != stdout) {
+  if (f != stdout) {
 fclose(f);
   }
 } // no-leak: 'fclose()' is always called because 'f' cannot be 'stdout'.
+
+void only_success_path_does_not_alias_with_stdout(void) {
+  if (stdout) return;
+  FILE *f = fopen("/tmp/foof", "r"); // no-crash
+  if (!f) return;
+  fclose(f);
+}

>From 7453968ac1764adbc70f867d43fa3d63473b09f3 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:39:03 +0200
Subject: [PATCH 2/6] NFC Fixup previous PR comment

Addresses:
https://github.com/llvm/llvm-project/pull/100085#discussion_r1688051166
---
 clang/test/Analysis/stream.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index 575b32d97be31..aff884f190c8e 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -499,14 +499,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fclose(f);
 }
 
-extern FILE *stdout_like_ptr;
-void no_aliasing(void) {
+extern FILE *non_standard_stream_ptr;
+void test_fopen_does_not_alias_with_standard_streams(void) {
   FILE *f = fopen("file", "r");
   if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
-  clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
+  clang_analyzer_eval(f == non_standard_stream_ptr); // expected-warning 
{{FALSE}} expected-warning {{TRUE}}
   if (f != stdout) {
 fclose(f);
   }

>From db92245ab09f195cbb859d85f2b93a81fd1b2617 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:46:16 +0200
Subject: [PATCH 3/6] NFC Fixup previous PR comment

Addresses
https://github.com/llvm/llvm-project/pull/100085#discussion_r1688054004
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 25 ++-
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 942e7541a83cd..4454f30630e27 100644
--- 

[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -1766,13 +1770,6 @@ are assumed to succeed.)
fclose(p);
  }
 
-**Limitations**
-
-The checker does not track the correspondence between integer file descriptors
-and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
-treated specially and are therefore often not recognized (because these streams
-are usually not opened explicitly by the program, and are global variables).

steakhal wrote:

Yea, but I didn't know exactly what it refers to. We could add an example for 
such a case there. That would help.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -1703,7 +1703,11 @@ are detected:
 * Invalid 3rd ("``whence``") argument to ``fseek``.
 
 The stream operations are by this checker usually split into two cases, a 
success
-and a failure case. However, in the case of write operations (like ``fwrite``,
+and a failure case.
+On the success case it also assumes that the current value of ``stdout``,
+``stderr``, or ``stdin`` can't be equal to the file pointer returned by 
``fopen``.
+
+In the case of write operations (like ``fwrite``,

steakhal wrote:

Same feeling. But I decided to opt for minimizing the diff. I still think that 
I made the right call.

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


[clang] [analyzer] Avoid crashes in the stream checker (PR #100901)

2024-07-29 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Avoid crashes in the stream checker (PR #100901)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

Thanks for the really valuable reduced case @vabridgers. I'll close this in 
favor of #100990 if you don't mind.
Thanks again for reporting the crash.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

I decided to put the fixup NFC changes along with this PR (the ones were 
submitted after I merged the original commit), but on hindsight probably it 
would be better to merge those NFC changes separately.
If you request, I'll split the PR.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits


@@ -1766,13 +1770,6 @@ are assumed to succeed.)
fclose(p);
  }
 
-**Limitations**
-
-The checker does not track the correspondence between integer file descriptors
-and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
-treated specially and are therefore often not recognized (because these streams
-are usually not opened explicitly by the program, and are global variables).

steakhal wrote:

I wasn't sure of this section, so I just removed it. Let me know if it's still 
relevant or not.

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


[clang] [analyzer] Fix crash of StreamChecker when eval calling 'fopen' (PR #100990)

2024-07-29 Thread Balazs Benics via cfe-commits

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

Actually, on the failure branch of `fopen`, the resulting pointer could
alias with `stdout` iff `stdout` is already known to be null.
We crashed in this case as the implementation assumed that the
state-split for creating the success and failure branches both should be
viable; thus dereferenced both of those states - leading to the crash.

To fix this, let's just only add this no-alias property for the success
path, and that's it :)

Fixes #100901

>From 12ff3274fce8dfe534e71abb9511d6549e32f74c Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:33:55 +0200
Subject: [PATCH 1/5] [analyzer] Fix crash of StreamChecker when eval calling
 'fopen'

Actually, on the failure branch of `fopen`, the resulting pointer could
alias with `stdout` iff `stdout` is already known to be null.
We crashed in this case as the implementation assumed that the
state-split for creating the success and failure branches both should be
viable; thus dereferenced both of those states - leading to the crash.

To fix this, let's just only add this no-alias property for the success
path, and that's it :)

Fixes #100901
---
 clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp |  3 ++-
 clang/test/Analysis/stream.c| 10 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 53770532609d5..942e7541a83cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -938,7 +938,6 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
-  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -951,6 +950,8 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   StateNull =
   StateNull->set(RetSym, StreamState::getOpenFailed(Desc));
 
+  StateNotNull = assumeNoAliasingWithStdStreams(StateNotNull, RetVal, C);
+
   C.addTransition(StateNotNull,
   constructLeakNoteTag(C, RetSym, "Stream opened here"));
   C.addTransition(StateNull);
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index b3a47ce4153d3..575b32d97be31 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -502,11 +502,19 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
 extern FILE *stdout_like_ptr;
 void no_aliasing(void) {
   FILE *f = fopen("file", "r");
+  if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
-  if (f && f != stdout) {
+  if (f != stdout) {
 fclose(f);
   }
 } // no-leak: 'fclose()' is always called because 'f' cannot be 'stdout'.
+
+void only_success_path_does_not_alias_with_stdout(void) {
+  if (stdout) return;
+  FILE *f = fopen("/tmp/foof", "r"); // no-crash
+  if (!f) return;
+  fclose(f);
+}

>From 7453968ac1764adbc70f867d43fa3d63473b09f3 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:39:03 +0200
Subject: [PATCH 2/5] NFC Fixup previous PR comment

Addresses:
https://github.com/llvm/llvm-project/pull/100085#discussion_r1688051166
---
 clang/test/Analysis/stream.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index 575b32d97be31..aff884f190c8e 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -499,14 +499,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fclose(f);
 }
 
-extern FILE *stdout_like_ptr;
-void no_aliasing(void) {
+extern FILE *non_standard_stream_ptr;
+void test_fopen_does_not_alias_with_standard_streams(void) {
   FILE *f = fopen("file", "r");
   if (!f) return;
   clang_analyzer_eval(f == stdin);   // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
   clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
-  clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expected-warning {{TRUE}}
+  clang_analyzer_eval(f == non_standard_stream_ptr); // expected-warning 
{{FALSE}} expected-warning {{TRUE}}
   if (f != stdout) {
 fclose(f);
   }

>From db92245ab09f195cbb859d85f2b93a81fd1b2617 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 29 Jul 2024 10:46:16 

[clang] [analyzer] Avoid crashes in the stream checker (PR #100901)

2024-07-29 Thread Balazs Benics via cfe-commits

steakhal wrote:

> In the state dump I see that `stdout` seems to be NULL (last line in 
> "constraints"). This explains why the `StateNull` becomes NULL, because call 
> to `assumeNoAliasingWithStdStreams` was called already. I think the better 
> solution is to check NULL-ness of the std stream variable 
> `assumeNoAliasingWithStdStreams` and do not assume if it is NULL. There is 
> not a case when `fopen` returns non-null for sure, but at least not in the 
> current situation, so the current fix is not as good. We could add an 
> `assert` to check if both `StateNull` and `StateNotNull` are non-zero.

Exactly. I didn't want to rush too much, but I can share that my current idea 
is to call `assumeNoAliasingWithStdStreams` only on the success path.

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


[clang] [analyzer] Keep alive short-circuiting condition subexpressions in a conditional (PR #100745)

2024-07-29 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Keep alive short-circuiting condition subexpressions in a conditional (PR #100745)

2024-07-26 Thread Balazs Benics via cfe-commits

steakhal wrote:

We'll merge this on Monday.

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


[clang] [analyzer][NFC] Eliminate a dyn_cast (PR #100719)

2024-07-26 Thread Balazs Benics via cfe-commits

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


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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-25 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-25 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-25 Thread Balazs Benics via cfe-commits


@@ -923,12 +923,31 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const {
   return UnknownVal();
 }
 
+static bool isWithinStdNamespace(const Decl *D) {

steakhal wrote:

Makes sense. I think I'd prefer moving this utility in a followup patch, as it 
may take a while to reach consensus where to put it. And I don't want to block 
this PR until that happens.

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


[clang] [Clang][Sema] Disallow applying `onwership_returns` to functions that return non-pointers (PR #99564)

2024-07-25 Thread Balazs Benics via cfe-commits

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

LGTM, thanks.

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


[clang] [clang][analyzer] MmapWriteExecChecker improvements (PR #97078)

2024-07-25 Thread Balazs Benics via cfe-commits
=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri?= ,
=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri?= 
Message-ID:
In-Reply-To: 


steakhal wrote:

Please make sure that the premerge bots are happy before merging.

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


[clang] [analyzer] Don't invalidate the super region when a std object ctor runs (PR #100405)

2024-07-24 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Don't invalidate super region when a std object ctor runs (PR #100405)

2024-07-24 Thread Balazs Benics via cfe-commits

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

CPP-5269

>From 95c0cd7f5d1c1a5c87707a5a63141dc3008191ed Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Wed, 24 Jul 2024 17:11:54 +0200
Subject: [PATCH] [analyzer] Don't invalidate super region when a std object
 ctor runs

CPP-5269
---
 clang/lib/StaticAnalyzer/Core/CallEvent.cpp |  19 
 clang/test/Analysis/call-invalidation.cpp   | 115 
 2 files changed, 134 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp 
b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 0e317ec765ec0..eba224b8ec01c 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -923,12 +923,31 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const {
   return UnknownVal();
 }
 
+static bool isWithinStdNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  while (DC) {
+if (const auto *NS = dyn_cast(DC);
+NS && NS->isStdNamespace())
+  return true;
+DC = DC->getParent();
+  }
+  return false;
+}
+
 void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList ,
RegionAndSymbolInvalidationTraits *ETraits) const {
   SVal V = getCXXThisVal();
   if (SymbolRef Sym = V.getAsSymbol(true))
 ETraits->setTrait(Sym,
   RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
+
+  // Standard classes don't reinterpret-cast and modify super regions.
+  const bool IsStdClassCtor = isWithinStdNamespace(getDecl());
+  if (const MemRegion *Obj = V.getAsRegion(); Obj && IsStdClassCtor) {
+ETraits->setTrait(
+Obj, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
+  }
+
   Values.push_back(V);
 }
 
diff --git a/clang/test/Analysis/call-invalidation.cpp 
b/clang/test/Analysis/call-invalidation.cpp
index 727217f228b05..fb2b892b31a1f 100644
--- a/clang/test/Analysis/call-invalidation.cpp
+++ b/clang/test/Analysis/call-invalidation.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify 
-analyzer-config eagerly-assume=false %s
 
+template  void clang_analyzer_dump(T);
 void clang_analyzer_eval(bool);
 
 void usePointer(int * const *);
@@ -165,3 +166,117 @@ void testMixedConstNonConstCalls() {
   useFirstNonConstSecondConst(&(s2.x), &(s2.y));
   clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}
 }
+
+namespace std {
+class Opaque {
+public:
+  Opaque();
+  int nested_member;
+};
+} // namespace std
+
+struct StdWrappingOpaque {
+  std::Opaque o; // first member
+  int uninit;
+};
+struct StdWrappingOpaqueSwapped {
+  int uninit; // first member
+  std::Opaque o;
+};
+
+int testStdCtorDoesNotInvalidateParentObject() {
+  StdWrappingOpaque obj;
+  int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might 
initialized this
+  int y = obj.uninit; // FIXME: We should have a garbage read here. Read the 
details.
+  // As the first member ("obj.o") is invalidated, a conjured default binding 
is bound
+  // to the offset 0 within cluster "obj", and this masks every uninitialized 
fields
+  // that follows. We need a better store with extents to fix this.
+  return x + y;
+}
+
+int testStdCtorDoesNotInvalidateParentObjectSwapped() {
+  StdWrappingOpaqueSwapped obj;
+  int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might 
initialized this
+  int y = obj.uninit; // expected-warning {{Assigned value is garbage or 
undefined}}
+  return x + y;
+}
+
+class UserProvidedOpaque {
+public:
+  UserProvidedOpaque(); // might reinterpret_cast(this)
+  int nested_member;
+};
+
+struct WrappingUserProvidedOpaque {
+  UserProvidedOpaque o; // first member
+  int uninit;
+};
+struct WrappingUserProvidedOpaqueSwapped {
+  int uninit; // first member
+  UserProvidedOpaque o;
+};
+
+int testUserProvidedCtorInvalidatesParentObject() {
+  WrappingUserProvidedOpaque obj;
+  int x = obj.o.nested_member; // no-garbage: UserProvidedOpaque::ctor might 
initialized this
+  int y = obj.uninit; // no-garbage: UserProvidedOpaque::ctor might 
reinterpret_cast(this) and write to the "uninit" member.
+  return x + y;
+}
+
+int testUserProvidedCtorInvalidatesParentObjectSwapped() {
+  WrappingUserProvidedOpaqueSwapped obj;
+  int x = obj.o.nested_member; // no-garbage: same as above
+  int y = obj.uninit; // no-garbage: same as above
+  return x + y;
+}
+
+struct WrappingStdWrappingOpaqueOuterInits {
+  int first = 1;
+  std::Opaque second;
+  int third = 3;
+  WrappingStdWrappingOpaqueOuterInits() {
+clang_analyzer_dump(first); // expected-warning {{1 S32b}}
+clang_analyzer_dump(second.nested_member); // expected-warning {{derived_}}
+clang_analyzer_dump(third); // expected-warning {{3 S32b}}
+  }
+};
+
+struct WrappingUserProvidedOpaqueOuterInits {
+  int first = 1; // Potentially overwritten by UserProvidedOpaque::ctor
+  UserProvidedOpaque second; // Invalidates the object so far.
+  int third = 

[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-24 Thread Balazs Benics via cfe-commits

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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-23 Thread Balazs Benics via cfe-commits

steakhal wrote:

Should I merge this PR, or you want to wait some?

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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-23 Thread Balazs Benics via cfe-commits

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


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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits


@@ -451,6 +462,10 @@ class StreamChecker : public Checker StdFileStreamDecls = {};
 
   void evalFopen(const FnDescription *Desc, const CallEvent ,
  CheckerContext ) const;
@@ -919,9 +918,8 @@ ProgramStateRef 
StreamChecker::assumeNoAliasingWithStdStreams(
   };
 
   assert(State);
-  State = assumeRetNE(State, StdinDecl);
-  State = assumeRetNE(State, StdoutDecl);
-  State = assumeRetNE(State, StderrDecl);
+  for (const VarDecl *VD : StdFileStreamDecls)
+State = assumeRetNE(State, VD);
   assert(State);
   return State;
 }
@@ -2082,9 +2080,11 @@ getGlobalStreamPointerByName(const TranslationUnitDecl 
*TU, StringRef VarName) {
 
 void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
  AnalysisManager &, BugReporter &) const {
-  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
-  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
-  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+  std::array DeclNames{"stdin", "stdout", "stderr"};
+  for (const auto &[DeclSlot, DeclName] :
+   llvm::zip_equal(StdFileStreamDecls, DeclNames)) {
+DeclSlot = getGlobalStreamPointerByName(TU, DeclName);
+  }
 }
 
 
//===--===//
```

In total, it replaces 9 lines with other 9 lines of code that is a lot more 
complicated and does an indirection. I'd say, not worth it.

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

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

>From c8148c88a39434501b9dacb374b3ca9d81ee8fdf Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Tue, 23 Jul 2024 08:55:16 +0200
Subject: [PATCH 1/2] [analyzer] Assume the result of 'fopen' can't alias with
 'std{in,out,err}'

'fopen' should return a new FILE handle, thus we should assume it can't
alias with commonly used FILE handles, such as with 'stdin', 'stdout' or
'stderr'.

This problem appears in code that handles either some input/output file
with stdin or stdout, as the business logic is basically the same no
matter the stream being used.
However, one would should only close the stream if it was opened via
'fopen'. Consequently, such code usually has a condition like
`if (f && f != stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking
the guarded branch.

CPP-5306
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 72 ++-
 clang/test/Analysis/stream.c  | 11 +++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto  = C.getStoreManager();
+auto  = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent ,
   CheckerContext ) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext  = TU->getASTContext();
+  const auto  = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup((VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 
//===--===//
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index c924cbd36f759..c518820df6ed6 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -498,3 +498,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fread(buffer, 1, 1, f); // expected-warning {{Stream pointer might be NULL}} 
no-crash
   fclose(f);
 }
+
+extern FILE *stdout_like_ptr;
+void no_aliasing(void) {
+  FILE *f = fopen("file", "r");
+  clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
+  clang_analyzer_eval(f == stderr);  // 

[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

steakhal wrote:

I didn't mention this in the release notes as I don't think it's that impactful.

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

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

'fopen' should return a new FILE handle, thus we should assume it can't alias 
with commonly used FILE handles, such as with 'stdin', 'stdout' or 'stderr'.

This problem appears in code that handles either some input/output file with 
stdin or stdout, as the business logic is basically the same no matter the 
stream being used.
However, one would should only close the stream if it was opened via 'fopen'. 
Consequently, such code usually has a condition like `if (f && f != stdout)` to 
guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking the 
guarded branch.

CPP-5306

>From c8148c88a39434501b9dacb374b3ca9d81ee8fdf Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Tue, 23 Jul 2024 08:55:16 +0200
Subject: [PATCH] [analyzer] Assume the result of 'fopen' can't alias with
 'std{in,out,err}'

'fopen' should return a new FILE handle, thus we should assume it can't
alias with commonly used FILE handles, such as with 'stdin', 'stdout' or
'stderr'.

This problem appears in code that handles either some input/output file
with stdin or stdout, as the business logic is basically the same no
matter the stream being used.
However, one would should only close the stream if it was opened via
'fopen'. Consequently, such code usually has a condition like
`if (f && f != stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking
the guarded branch.

CPP-5306
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 72 ++-
 clang/test/Analysis/stream.c  | 11 +++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto  = C.getStoreManager();
+auto  = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent ,
   CheckerContext ) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent ,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext  = TU->getASTContext();
+  const auto  = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup((VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 

[clang] [analyzer] Model builtin-like functions as builtin functions (PR #99886)

2024-07-22 Thread Balazs Benics via cfe-commits

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

Some template function instantiations don't have a body, even though their 
templates did have a body.
Examples are: `std::move`, `std::forward`, `std::addressof` etc.

They had bodies before
https://github.com/llvm/llvm-project/commit/72315d02c432a0fe0acae9c96c69eac8d8e1a9f6

After that change, the sentiment was that these special functions should be 
considered and treated as builtin functions.

Fixes #94193

CPP-5358

>From 3f25761041417de42330b348d46f35ac5af99426 Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 22 Jul 2024 15:59:23 +0200
Subject: [PATCH] [analyzer] Model builtin-like functions as builtin functions

Some template function instantiations don't have a body, even though
their templates did have a body.
Examples are: `std::move`, `std::forward`, `std::addressof` etc.

They had bodies before
https://github.com/llvm/llvm-project/commit/72315d02c432a0fe0acae9c96c69eac8d8e1a9f6

After that change, the sentiment was that these special funtions
should be considered and treated as builtin functions.

Fixes #94193

CPP-5358
---
 clang/docs/ReleaseNotes.rst   |  4 ++
 .../Checkers/BuiltinFunctionChecker.cpp   | 38 +
 .../Inputs/system-header-simulator-cxx.h  | 14 ---
 clang/test/Analysis/builtin-functions.cpp | 20 +
 .../diagnostics/explicit-suppression.cpp  |  2 +-
 clang/test/Analysis/issue-94193.cpp   | 41 +++
 clang/test/Analysis/use-after-move.cpp|  9 +---
 7 files changed, 114 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/Analysis/issue-94193.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 61629ff30aeeb..4ddb6baa49824 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1326,6 +1326,10 @@ Crash and bug fixes
 - Z3 crosschecking (aka. Z3 refutation) is now bounded, and can't consume
   more total time than the eymbolic execution itself. (#GH97298)
 
+- ``std::addressof``, ``std::as_const``, ``std::forward``,
+  ``std::forward_like``, ``std::move``, ``std::move_if_noexcept``, are now
+  modeled just like their builtin counterpart. (#GH94193)
+
 Improvements
 
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 1a75d7b52ad6e..b198b1c2ff4d1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -18,6 +18,7 @@
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
@@ -30,8 +31,40 @@ namespace {
 class BuiltinFunctionChecker : public Checker {
 public:
   bool evalCall(const CallEvent , CheckerContext ) const;
+
+private:
+  // From: clang/include/clang/Basic/Builtins.def
+  // C++ standard library builtins in namespace 'std'.
+  const CallDescriptionSet BuiltinLikeStdFunctions{
+  {CDM::SimpleFunc, {"std", "addressof"}},//
+  {CDM::SimpleFunc, {"std", "__addressof"}},  //
+  {CDM::SimpleFunc, {"std", "as_const"}}, //
+  {CDM::SimpleFunc, {"std", "forward"}},  //
+  {CDM::SimpleFunc, {"std", "forward_like"}}, //
+  {CDM::SimpleFunc, {"std", "move"}}, //
+  {CDM::SimpleFunc, {"std", "move_if_noexcept"}}, //
+  };
+
+  bool isBuiltinLikeFunction(const CallEvent ) const;
 };
 
+} // namespace
+
+bool BuiltinFunctionChecker::isBuiltinLikeFunction(
+const CallEvent ) const {
+  const auto *FD = llvm::dyn_cast_or_null(Call.getDecl());
+  if (!FD || FD->getNumParams() != 1)
+return false;
+
+  if (QualType RetTy = FD->getReturnType();
+  !RetTy->isPointerType() && !RetTy->isReferenceType())
+return false;
+
+  if (QualType ParmTy = FD->getParamDecl(0)->getType();
+  !ParmTy->isPointerType() && !ParmTy->isReferenceType())
+return false;
+
+  return BuiltinLikeStdFunctions.contains(Call);
 }
 
 bool BuiltinFunctionChecker::evalCall(const CallEvent ,
@@ -44,6 +77,11 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent ,
   const LocationContext *LCtx = C.getLocationContext();
   const Expr *CE = Call.getOriginExpr();
 
+  if (isBuiltinLikeFunction(Call)) {
+C.addTransition(state->BindExpr(CE, LCtx, Call.getArgSVal(0)));
+return true;
+  }
+
   switch (FD->getBuiltinID()) {
   default:
 return false;
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h 
b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h
index 29326ec1f9280..a379a47515668 

[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-22 Thread Balazs Benics via cfe-commits
=?utf-8?q?Krist=C3=B3f?= Umann ,
=?utf-8?q?Krist=C3=B3f?= Umann ,
=?utf-8?q?Krist=C3=B3f?= Umann ,
=?utf-8?q?Krist=C3=B3f?= Umann ,
=?utf-8?q?Krist=C3=B3f?= Umann 
Message-ID:
In-Reply-To: 


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


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


[clang] [analyzer] Improve bug report hashing, merge similar reports (PR #98621)

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


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


[clang] [analyzer] Improve bug report hashing, merge similar reports (PR #98621)

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



@@ -2213,7 +2213,7 @@ void BasicBugReport::Profile(llvm::FoldingSetNodeID& 
hash) const {
 void PathSensitiveBugReport::Profile(llvm::FoldingSetNodeID ) const {
   hash.AddInteger(static_cast(getKind()));
   hash.AddPointer();
-  hash.AddString(Description);
+  hash.AddString(getShortDescription());

steakhal wrote:

Is it intentional that you use a member function here instead of the member 
variable?

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


[clang] [analyzer] Improve bug report hashing, merge similar reports (PR #98621)

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


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

LGTM. I only had one minor question inline.

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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-18 Thread Balazs Benics via cfe-commits

steakhal wrote:

> > and you can read the docs for the checker, and the attribute at the links.
> 
> I can't find any docs for this attribute. As I mentioned, I will fill new 
> issues to fix couple of frontend issues and after that we can write down 
> correct semantics of these attrs.

Thats fine.

> Do you mean that link 
> https://clang.llvm.org/docs/AttributeReference.html#ownership-holds-ownership-returns-ownership-takes?

Yes. Its generated from a tablegen file. Thats why you probably didnt find it.
Look for files with the "td" extension, and  "attr" in name. May have a 
different casing though. Watch out.



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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-18 Thread Balazs Benics via cfe-commits

steakhal wrote:

FYI This PR is still not mentioned in the `clang/docs/ReleaseNotes.rst`.
We should have two entries there:
 1) In [Attribute Changes in 
Clang](https://github.com/llvm/llvm-project/blob/main/clang/docs/ReleaseNotes.rst#id34),
 mentioning that calls can have at most one `ownership_return` attribute.
 2) In [Static Analyzer > New 
features](https://github.com/llvm/llvm-project/blob/main/clang/docs/ReleaseNotes.rst#id47),
 that the MallocChecker now checks this attribute, and you can read the docs 
for the checker, and the attribute at the links.

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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-18 Thread Balazs Benics via cfe-commits

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,16 +1923,43 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {
+const FunctionDecl *FD = CE->getDirectCallee();
+if (!FD)
+  return;
+
+if (!FD->hasAttrs())
+  return;
+
+// Only one ownership_takes attribute is allowed
+for (const auto *I : FD->specific_attrs()) {
+  OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
+
+  if (OwnKind != OwnershipAttr::Takes)

steakhal wrote:

```suggestion
  if (I->getOwnKind() != OwnershipAttr::Takes)
```
It seems like inlining this variable would make it more readable actually.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,16 +1923,43 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {

steakhal wrote:

When I advocated for early-returns, I wanted something like this:
```c++
const auto *CE = dyn_cast(E);
if (!CE)
  return;
const FunctionDecl *FD = CE->getDirectCallee();
if (!FD)
  return;
  ...
```
On the same token, the `FD->hasAttrs()` appears to be not strictly necessary as 
in that case the loop simply wouldn't take any iterations at all, right?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,16 +1923,43 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {
+const FunctionDecl *FD = CE->getDirectCallee();
+if (!FD)
+  return;
+
+if (!FD->hasAttrs())
+  return;
+
+// Only one ownership_takes attribute is allowed

steakhal wrote:

```suggestion
// Only one ownership_takes attribute is allowed.
```

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,16 +1923,43 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {
+const FunctionDecl *FD = CE->getDirectCallee();
+if (!FD)
+  return;
+
+if (!FD->hasAttrs())
+  return;
+
+// Only one ownership_takes attribute is allowed
+for (const auto *I : FD->specific_attrs()) {
+  OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
+
+  if (OwnKind != OwnershipAttr::Takes)
+continue;
+
+  os << ", which takes ownership of " << '\'' << I->getModule()->getName()
+ << '\'';

steakhal wrote:

```suggestion
  os << ", which takes ownership of '" << I->getModule()->getName() << '\'';
```
This way it would even fit into a single line.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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

I think it looks great.
Only a few more stylistic remarks are left, but it should be already in a good 
shape functional-wise. I'll let you decide if you wanna apply my suggestions or 
not.

One more remark - this time w.r.t. the workflow. Usually, GitHub PRs prefer 
"merges" over "force-pushes". Whenever you force-push, all the inline remarks 
could get lost, as it fails to track the lines where the comments were made. 
Thus, when working with PRs, one usually just "merges" the tracked branch, and 
just builds more and more commits on top of your PR branch. Once the review is 
done, one is free to destroy the history and squash the commits, or do some 
reordering - because there are no more pending comments or remarks left.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,49 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+struct AllocationFamily {
+  AllocationFamilyKind Kind;
+  std::optional CustomName;
+
+  explicit AllocationFamily(AllocationFamilyKind kind,
+std::optional name = std::nullopt)
+  : Kind(kind), CustomName(name) {
+assert(kind != AF_Custom || name != std::nullopt);
+
+// Preseve previous behavior when "malloc" class means AF_Malloc
+if (Kind == AF_Malloc && CustomName) {
+  if (CustomName.value() == "malloc")
+CustomName = std::nullopt;
+  else
+Kind = AF_Custom;
+}
+  }
+
+  bool operator==(const AllocationFamily ) const {
+return std::tie(Kind, CustomName) == std::tie(Other.Kind, 
Other.CustomName);
+  }
+
+  bool operator!=(const AllocationFamily ) const {
+return !(*this == Other);
+  }
+
+  void Profile(llvm::FoldingSetNodeID ) const {
+ID.AddInteger(Kind);
+
+if (Kind == AF_Custom)
+  ID.AddString(CustomName.value());
+  }

steakhal wrote:

Ah indeed. nvm.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1122,7 +1157,7 @@ MallocChecker::performKernelMalloc(const CallEvent , 
CheckerContext ,
   if (TrueState && !FalseState) {
 SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
 return MallocMemAux(C, Call, Call.getArgExpr(0), ZeroVal, TrueState,
-AF_Malloc);
+AllocationFamily(AF_Malloc));

steakhal wrote:

Now I get what you meant when pushed back on adding `explicit`. I didn't expect 
this to cause such a widespread effect. Sorry. Now that you made all the 
necessary changes, we can keep it as-is. You decide if you prefer reverting 
these back. I'm good either way.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,49 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+struct AllocationFamily {
+  AllocationFamilyKind Kind;
+  std::optional CustomName;
+
+  explicit AllocationFamily(AllocationFamilyKind kind,
+std::optional name = std::nullopt)
+  : Kind(kind), CustomName(name) {
+assert(kind != AF_Custom || name != std::nullopt);
+
+// Preseve previous behavior when "malloc" class means AF_Malloc
+if (Kind == AF_Malloc && CustomName) {
+  if (CustomName.value() == "malloc")
+CustomName = std::nullopt;
+  else
+Kind = AF_Custom;
+}
+  }
+
+  bool operator==(const AllocationFamily ) const {
+return std::tie(Kind, CustomName) == std::tie(Other.Kind, 
Other.CustomName);
+  }
+
+  bool operator!=(const AllocationFamily ) const {
+return !(*this == Other);
+  }
+
+  void Profile(llvm::FoldingSetNodeID ) const {
+ID.AddInteger(Kind);
+
+if (Kind == AF_Custom)
+  ID.AddString(CustomName.value());
+  }

steakhal wrote:

I think you could also do this unconditionally.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,49 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+struct AllocationFamily {
+  AllocationFamilyKind Kind;
+  std::optional CustomName;
+
+  explicit AllocationFamily(AllocationFamilyKind kind,
+std::optional name = std::nullopt)
+  : Kind(kind), CustomName(name) {
+assert(kind != AF_Custom || name != std::nullopt);
+
+// Preseve previous behavior when "malloc" class means AF_Malloc
+if (Kind == AF_Malloc && CustomName) {
+  if (CustomName.value() == "malloc")
+CustomName = std::nullopt;
+  else
+Kind = AF_Custom;
+}

steakhal wrote:

Probably I don't understand the semantics of this one.
I was expecting that the `CustomName` field is only used when the `Kind` is 
`AF_Custom`. Yet, here it appears to be used even for `Kind == AF_Malloc`.

What I originally thought that when `AF_Custom` is specified with `"malloc"`, 
then it should consider the case as `AF_Malloc` instead.
Could you elaborate here?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1490,7 +1532,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocCheck(
   return State;
 }
   } else
-llvm_unreachable("not a CallExpr or CXXNewExpr");
+assert(false && "not a CallExpr or CXXNewExpr");

steakhal wrote:

```suggestion
  } else {
assert(false && "not a CallExpr or CXXNewExpr");
return nullptr;
  }
```
Just to be on the safe side and we have a NDEBUG build (with assertions 
disabled), let's avoid undefined behavior by safely backing off.

The same principle should apply to all the other cases when previously we had 
an `llvm_unreachable`.
This is what I wanted to imply by `assert and return`.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,49 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+struct AllocationFamily {
+  AllocationFamilyKind Kind;
+  std::optional CustomName;
+
+  explicit AllocationFamily(AllocationFamilyKind kind,
+std::optional name = std::nullopt)

steakhal wrote:

Please use upper camel case for variable names. Shadowing is not a problem for 
constructor parameters and init-lists, and within the ctor body the semantics 
are anyways well-defined.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);

steakhal wrote:

Interesting.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,49 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+struct AllocationFamily {
+  AllocationFamilyKind Kind;
+  std::optional CustomName;
+
+  explicit AllocationFamily(AllocationFamilyKind kind,
+std::optional name = std::nullopt)
+  : Kind(kind), CustomName(name) {
+assert(kind != AF_Custom || name != std::nullopt);

steakhal wrote:

I'd prefer to have a message here to be able to immediately tell what this 
assert is about when fires.
```suggestion
assert((kind != AF_Custom || name.has_value()) && "Custom family must 
specify also the name");
```

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -24,3 +24,7 @@ void f15(int, int)
 void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) 
__attribute__((ownership_holds(foo, 1))); // OK, same index
 void f17(void*) __attribute__((ownership_takes(__, 1)));
 void f18() __attribute__((ownership_takes(foo, 1)));  // expected-warning 
{{'ownership_takes' attribute only applies to non-K functions}}
+
+int f19(void *)
+  __attribute__((ownership_takes(foo, 1)))// expected-error 
{{'ownership_takes' attribute class does not match; here it is 'foo'}}
+  __attribute__((ownership_takes(foo1, 1)));  // expected-note {{declared with 
class 'foo1' here}}

steakhal wrote:

What happens if I want to redeclare the function with a different 
"ownership_takes" attribute in a subsequent line? Will it detect the conflict?
```
int f20(void *) __attribute__((ownership_takes(foo, 1)));
int f20(void *) __attribute__((ownership_takes(foo1, 1))); // redecl with 
different attr
```

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

https://github.com/steakhal commented:

It looks great! I only had one more thing to test.
Besides that it would be nice to advertise this in the 
`clang/docs/ReleaseNotes.rst`.
Usually, from that release notes we also link to the checker or the relevant 
doc pages - in this case it would be nice to link to the docs of this attribute 
- which does not really elaborate on the attribute and the semantics.

Do you want to extend the scope of this PR to add some minimal docs to the 
attribute?
If not, that's also fine, we will create a separate ticket for adding them 
later.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -60,6 +67,41 @@ void testMalloc8() {
   operator delete[](p); // expected-warning{{Memory allocated by malloc() 
should be deallocated by free(), not operator delete[]}}
 }
 
+void testMalloc9() {
+  int *p = (int *)my_malloc(sizeof(int));
+  my_free(p); // no warning
+}
+
+void testMalloc10() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free1(p); // no warning
+}
+
+void testMalloc11() {
+  int *p = (int *)my_malloc2(sizeof(int));
+  my_free23(p); // no warning
+}
+
+void testMalloc12() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free(p); // expected-warning{{Memory allocated by my_malloc1() should be 
deallocated by function that takes ownership of 'malloc1', not my_free(), which 
takes ownership of 'malloc'}}

steakhal wrote:

Ah, I see. The phrasing wasn't clear to me. Maybe because we don't have a clear 
spec for this attribute, thus it's difficult to make out things that have 
special meaning.
I think we should quote function names, yes.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,

steakhal wrote:

I'd prefer having this explicit.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
+void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);
+
+void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);
+void __attribute((ownership_returns(malloc2))) *my_malloc3(size_t);
+void __attribute((ownership_takes(malloc2, 1))) 
__attribute((ownership_takes(malloc3, 1))) my_free23(void *);

steakhal wrote:

To me, it would make more sense to allow at most one of this attribute to be 
present.

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -346,6 +350,36 @@ class CompoundVal : public NonLoc {
   static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
 };
 
+/// While nonloc::CompoundVal covers a few simple use cases,
+/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
+/// an rvalue of record type, so it shows up much more frequently during
+/// analysis. This value is an r-value that represents a snapshot of any
+/// structure "as a whole" at a given moment during the analysis. Such value is
+/// already quite far from being referred to as "concrete", as many fields
+/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
+/// storing two things:
+///   * a reference to the TypedValueRegion being snapshotted (yes, it is 
always
+/// typed), and also
+///  * a reference to the whole Store object, obtained from the ProgramState in
+///which the nonloc::LazyCompoundVal was created.

steakhal wrote:

These bulletpoints are indented by different levels.

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -346,6 +350,36 @@ class CompoundVal : public NonLoc {
   static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
 };
 
+/// While nonloc::CompoundVal covers a few simple use cases,
+/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
+/// an rvalue of record type, so it shows up much more frequently during
+/// analysis. This value is an r-value that represents a snapshot of any
+/// structure "as a whole" at a given moment during the analysis. Such value is
+/// already quite far from being referred to as "concrete", as many fields
+/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
+/// storing two things:
+///   * a reference to the TypedValueRegion being snapshotted (yes, it is 
always
+/// typed), and also
+///  * a reference to the whole Store object, obtained from the ProgramState in
+///which the nonloc::LazyCompoundVal was created.
+///
+/// Note that the old ProgramState and its Store is kept alive during the
+/// analysis because these are immutable functional data structures and each 
new
+/// Store value is represented as "earlier Store" + "additional binding".
+///
+/// Essentially, nonloc::LazyCompoundVal is a performance optimization for the
+/// analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is
+/// a very cheap operation. Note that the Store contains all region bindings in
+/// the program state, not only related to the region. Later, if necessary, 
such
+/// value can be unpacked -- eg. when it is assigned to another variable.
+///
+/// If you ever need inspect the contents of the LazyCompoundVal, you can use

steakhal wrote:

```suggestion
/// If you ever need to inspect the contents of the LazyCompoundVal, you can use
```

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 


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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -363,6 +397,18 @@ class LazyCompoundVal : public NonLoc {
   /// It might return null.
   const void *getStore() const;
 
+  /// This function itself is immaterial. It is only an implementation detail.
+  /// LazyCompoundVal represents only the rvalue, the data (known or unknown)
+  /// that *was* stored in that region *at some point in the past*. The region
+  /// should not be used for any purpose other than figuring out what part of
+  /// the frozen Store you're interested in. The value does not represent the
+  /// *current* value of that region. Sometimes it may, but this should not be
+  /// relied upon. Instead, if you want to figure out what region it 
represents,
+  /// you typically need to see where you got it from in the first place. The
+  /// region is absolutely not analogous to the C++ "this" pointer. It is also
+  /// not a valid way to "materialize" the prvalue into a glvalue in C++,
+  /// because the region represents the *old* storage (sometimes very old), not
+  /// the *future* storage.

steakhal wrote:

To be fair, I don't really understand this.

To me, this region is the region that one would need to query from the 
associated `Store` to get the value this `LazyCompoundValue` actually boils 
down to.
So, a region, like every other region, only defines a memory location (an 
l-value), and there is not much one could do with such a region. But I find 
this true for any other `MemRegion` anywhere in the engine.

Probably I miss something, as I don't usually deal with LCVs, and it's been a 
while I last touched them.
So, to summarize, I don't really understand what `immaterial` means in this 
context or understand why we mention it for `LCV::getRegion()` instead of 
mention this for a `MemRegion`.

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 


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

I think it's already in a good shape. I found barely any problems with the 
wording.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -3483,53 +3578,54 @@ PathDiagnosticPieceRef 
MallocBugVisitor::VisitNode(const ExplodedNode *N,
   Sym, "Returned allocated memory");
 } else if (isReleased(RSCurr, RSPrev, S)) {
   const auto Family = RSCurr->getAllocationFamily();
-  switch (Family) {
-case AF_Alloca:
-case AF_Malloc:
-case AF_CXXNew:
-case AF_CXXNewArray:
-case AF_IfNameIndex:
-  Msg = "Memory is released";
+  switch (Family.kind()) {
+  case AF_Alloca:
+  case AF_Malloc:
+  case AF_Custom:
+  case AF_CXXNew:
+  case AF_CXXNewArray:
+  case AF_IfNameIndex:
+Msg = "Memory is released";
+StackHint = std::make_unique(
+Sym, "Returning; memory was released");
+break;
+  case AF_InnerBuffer: {
+const MemRegion *ObjRegion =
+allocation_state::getContainerObjRegion(statePrev, Sym);
+const auto *TypedRegion = cast(ObjRegion);
+QualType ObjTy = TypedRegion->getValueType();
+OS << "Inner buffer of '" << ObjTy << "' ";
+
+if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) {
+  OS << "deallocated by call to destructor";
   StackHint = std::make_unique(
-  Sym, "Returning; memory was released");
-  break;
-case AF_InnerBuffer: {
-  const MemRegion *ObjRegion =
-  allocation_state::getContainerObjRegion(statePrev, Sym);
-  const auto *TypedRegion = cast(ObjRegion);
-  QualType ObjTy = TypedRegion->getValueType();
-  OS << "Inner buffer of '" << ObjTy << "' ";
-
-  if (N->getLocation().getKind() == 
ProgramPoint::PostImplicitCallKind) {
-OS << "deallocated by call to destructor";
-StackHint = std::make_unique(
-Sym, "Returning; inner buffer was deallocated");
-  } else {
-OS << "reallocated by call to '";
-const Stmt *S = RSCurr->getStmt();
-if (const auto *MemCallE = dyn_cast(S)) {
-  OS << MemCallE->getMethodDecl()->getDeclName();
-} else if (const auto *OpCallE = dyn_cast(S)) 
{
-  OS << OpCallE->getDirectCallee()->getDeclName();
-} else if (const auto *CallE = dyn_cast(S)) {
-  auto  = BRC.getStateManager().getCallEventManager();
-  CallEventRef<> Call =
-  CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0});
-  if (const auto *D = dyn_cast_or_null(Call->getDecl()))
-OS << D->getDeclName();
-  else
-OS << "unknown";
-}
-OS << "'";
-StackHint = std::make_unique(
-Sym, "Returning; inner buffer was reallocated");
+  Sym, "Returning; inner buffer was deallocated");
+} else {
+  OS << "reallocated by call to '";
+  const Stmt *S = RSCurr->getStmt();
+  if (const auto *MemCallE = dyn_cast(S)) {
+OS << MemCallE->getMethodDecl()->getDeclName();
+  } else if (const auto *OpCallE = dyn_cast(S)) {
+OS << OpCallE->getDirectCallee()->getDeclName();
+  } else if (const auto *CallE = dyn_cast(S)) {
+auto  = BRC.getStateManager().getCallEventManager();
+CallEventRef<> Call =
+CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0});
+if (const auto *D = dyn_cast_or_null(Call->getDecl()))
+  OS << D->getDeclName();
+else
+  OS << "unknown";
   }
-  Msg = OS.str();
-  break;
+  OS << "'";
+  StackHint = std::make_unique(
+  Sym, "Returning; inner buffer was reallocated");
 }
+Msg = OS.str();
+break;
+  }
 case AF_None:
   llvm_unreachable("Unhandled allocation family!");

steakhal wrote:

This isn't part of your current patch, but I'd suggest turning this into an 
assert and return too.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);

steakhal wrote:

What happens if you have a forward declaration to a malloc function without the 
attribute, then later have another redeclaration with the `ownership_returns` 
attribute?
A similar case to test would be the opposite: 1st declaration has the 
attribute, the second redeclaration would not have the attribute.
I suspect that the FunctionDecl of the callees will refer to the last seen 
declaration of the function, thus, will not recognize the attribute for the 
second case I mentioned here.
Could you test these cases?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,6 +1914,33 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {
+const FunctionDecl *FD = CE->getDirectCallee();
+if (!FD)
+  return;
+
+if (FD->hasAttrs()) {

steakhal wrote:

You could switch this into an early-return to reduce indentation for the rest 
of the code.
Same applies to the `if (const CallExpr *CE = dyn_cast(E))` a few 
lines above.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
+void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);
+
+void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);
+void __attribute((ownership_returns(malloc2))) *my_malloc3(size_t);
+void __attribute((ownership_takes(malloc2, 1))) 
__attribute((ownership_takes(malloc3, 1))) my_free23(void *);

steakhal wrote:

I'm surprised to see that a function can have two different `ownership_takes` 
attributes.
Are you sure that this is the case? If so, why is that?

Have you considered adding some documentation to the attributes page, and to 
the Malloc checker to highlight this attribute?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,
+   std::optional name = std::nullopt)
+  : _kind(kind), _customName(name) {
+assert(kind != AF_Custom || name != std::nullopt);
+  }
+
+  bool operator==(const AllocationFamily ) const {
+if (Other.kind() == this->kind()) {
+  return this->kind() == AF_Custom ? this->_customName == Other._customName
+   : true;
+} else {
+  return false;
+}
+  }
+
+  bool operator==(const AllocationFamilyKind ) {
+return this->kind() == kind;
+  }
+
+  bool operator!=(const AllocationFamilyKind ) { return !(*this == kind); 
}

steakhal wrote:

Could you define this for the class type instead?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1918,26 +1982,54 @@ static bool printMemFnName(raw_ostream , 
CheckerContext , const Expr *E) {
 
 static void printExpectedAllocName(raw_ostream , AllocationFamily Family) {
 
-  switch(Family) {
-case AF_Malloc: os << "malloc()"; return;
-case AF_CXXNew: os << "'new'"; return;
-case AF_CXXNewArray: os << "'new[]'"; return;
-case AF_IfNameIndex: os << "'if_nameindex()'"; return;
-case AF_InnerBuffer: os << "container-specific allocator"; return;
-case AF_Alloca:
-case AF_None: llvm_unreachable("not a deallocation expression");
+  switch (Family.kind()) {
+  case AF_Malloc:
+os << "malloc()";
+return;
+  case AF_CXXNew:
+os << "'new'";
+return;
+  case AF_CXXNewArray:
+os << "'new[]'";
+return;
+  case AF_IfNameIndex:
+os << "'if_nameindex()'";
+return;
+  case AF_InnerBuffer:
+os << "container-specific allocator";
+return;
+  case AF_Custom:
+os << Family.name().value();
+return;
+  case AF_Alloca:
+  case AF_None:
+llvm_unreachable("not a deallocation expression");
   }
 }
 
 static void printExpectedDeallocName(raw_ostream , AllocationFamily Family) 
{
-  switch(Family) {
-case AF_Malloc: os << "free()"; return;
-case AF_CXXNew: os << "'delete'"; return;
-case AF_CXXNewArray: os << "'delete[]'"; return;
-case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
-case AF_InnerBuffer: os << "container-specific deallocator"; return;
-case AF_Alloca:
-case AF_None: llvm_unreachable("suspicious argument");
+  switch (Family.kind()) {
+  case AF_Malloc:
+os << "free()";
+return;
+  case AF_CXXNew:
+os << "'delete'";
+return;
+  case AF_CXXNewArray:
+os << "'delete[]'";
+return;
+  case AF_IfNameIndex:
+os << "'if_freenameindex()'";
+return;
+  case AF_InnerBuffer:
+os << "container-specific deallocator";
+return;
+  case AF_Custom:
+os << "function that takes ownership of '" << Family.name().value() << 
"\'";
+return;
+  case AF_Alloca:
+  case AF_None:
+llvm_unreachable("suspicious argument");

steakhal wrote:

Same goes here, use a regular `assert` and `return`.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,
+   std::optional name = std::nullopt)
+  : _kind(kind), _customName(name) {
+assert(kind != AF_Custom || name != std::nullopt);
+  }
+
+  bool operator==(const AllocationFamily ) const {
+if (Other.kind() == this->kind()) {
+  return this->kind() == AF_Custom ? this->_customName == Other._customName
+   : true;
+} else {
+  return false;
+}
+  }
+
+  bool operator==(const AllocationFamilyKind ) {
+return this->kind() == kind;
+  }
+
+  bool operator!=(const AllocationFamilyKind ) { return !(*this == kind); 
}
+
+  std::optional name() const { return _customName; }
+  AllocationFamilyKind kind() const { return _kind; }
+
+private:
+  AllocationFamilyKind _kind;
+  std::optional _customName;

steakhal wrote:

I think it should be fine to have these fields as public members, given the 
complexity of this class. This is basically a std::pair. Feel free to use 
`struct` instead of `class`.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1877,6 +1914,33 @@ static bool didPreviousFreeFail(ProgramStateRef State,
   return false;
 }
 
+static void printOwnershipTakesList(raw_ostream , CheckerContext ,
+const Expr *E) {
+  if (const CallExpr *CE = dyn_cast(E)) {
+const FunctionDecl *FD = CE->getDirectCallee();
+if (!FD)
+  return;
+
+if (FD->hasAttrs()) {
+  bool attrPrinted = false;
+
+  for (const auto *I : FD->specific_attrs()) {
+OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
+
+if (OwnKind == OwnershipAttr::Takes) {
+  if (attrPrinted)
+os << ", ";
+  else
+os << ", which takes ownership of ";
+
+  os << '\'' << I->getModule()->getName() << "'";

steakhal wrote:

You use single quoted char and double quoted char. I just highlight this 
inconsistency.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -194,7 +226,7 @@ class RefState {
   void Profile(llvm::FoldingSetNodeID ) const {
 ID.AddInteger(K);
 ID.AddPointer(S);
-ID.AddInteger(Family);
+ID.AddInteger(Family.kind());

steakhal wrote:

This Profile wouldn't take the custom allocation function name into account.
I'd suggest letting the Family define its own Profile method and just pass the 
ID to it.
That is the canonical way of doing this.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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

Looks pretty good. Thanks for working on the issue.
I didn't see any major blocking issue with the PR, so good job on that!

Overall, be sure to follow the llvm [coding 
style](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly),
 including using upper case variable names.

Thanks again for working on this :)

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -1918,26 +1982,54 @@ static bool printMemFnName(raw_ostream , 
CheckerContext , const Expr *E) {
 
 static void printExpectedAllocName(raw_ostream , AllocationFamily Family) {
 
-  switch(Family) {
-case AF_Malloc: os << "malloc()"; return;
-case AF_CXXNew: os << "'new'"; return;
-case AF_CXXNewArray: os << "'new[]'"; return;
-case AF_IfNameIndex: os << "'if_nameindex()'"; return;
-case AF_InnerBuffer: os << "container-specific allocator"; return;
-case AF_Alloca:
-case AF_None: llvm_unreachable("not a deallocation expression");
+  switch (Family.kind()) {
+  case AF_Malloc:
+os << "malloc()";
+return;
+  case AF_CXXNew:
+os << "'new'";
+return;
+  case AF_CXXNewArray:
+os << "'new[]'";
+return;
+  case AF_IfNameIndex:
+os << "'if_nameindex()'";
+return;
+  case AF_InnerBuffer:
+os << "container-specific allocator";
+return;
+  case AF_Custom:
+os << Family.name().value();
+return;
+  case AF_Alloca:
+  case AF_None:
+llvm_unreachable("not a deallocation expression");

steakhal wrote:

I'd suggest swapping this `llvm_unreachable` to an `assert(false && "not a 
deallocation expression"); return;` as this code is probably not in the hot 
path, thus the use of `llvm_unreachable` is unjustified.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
+void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);
+
+void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);
+void __attribute((ownership_returns(malloc2))) *my_malloc3(size_t);

steakhal wrote:

This looks suspiciously similar to `my_malloc2`, are you sure you don't have a 
type somewhere?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,

steakhal wrote:

I'd suggest marking this `explicit`.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Improve bug report hashing, merge similar reports (PR #98621)

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


steakhal wrote:

> _(Technical detail: I'll be on vacation during the next week, so I won't see 
> updates on this PR until the 22nd of July. If you want to merge this PR, feel 
> free to do so.)_ 

No need to rush. Have a nice one!

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


[clang] [analyzer] Don't display the offset value in underflows (PR #98621)

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

https://github.com/steakhal commented:

This makes sense.
I wonder if we could have something in between. I'm thinking of having the 
concrete offset as a separate note, instead of having it part of the primary 
message.
That way after BR selection, we would still deterministically pick the shortest 
parh, and also have the offset in the path notes.

I find this better than dropping the concrete offset you worked so hard 
acquiring. WDYT?

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


[clang] [analyzer][docs] Add clang-19 release notes for CSA (PR #97418)

2024-07-10 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Split TaintPropagation checker into reporting and modeling checkers (PR #98157)

2024-07-10 Thread Balazs Benics via cfe-commits


@@ -1046,10 +1044,7 @@ bool GenericTaintChecker::generateReportIfTainted(const 
Expr *E, StringRef Msg,
 return false;
 
   // Generate diagnostic.

steakhal wrote:

If we are there, maybe we should also assert that inside the register call, 
before emplacing it was empty.

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


  1   2   3   4   5   6   7   8   9   10   >