[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-10-31 Thread Balazs Benics via cfe-commits

steakhal wrote:

This is a brief summary of my recent investigation, no direct action is 
required.

I had a quick look at the issue differences between clang-17 and llvm/main as a 
preparation for the clang-18 release in early January and noticed that because 
of this patch, we have some unexpected improvements.
FYI this FP was eliminated by Z3 refutation anyway if you enabled that, but now 
even the engine can avoid exploring that dead-code.

---

Now that we simplify more often (see the patch), we can exclude more execution 
paths.
Here is an [example](https://godbolt.org/z/x35MT33xT):

```C++
int fixedFP(int x) {
  int* z = 0;
  if ((x & 1) && ((x & 1) ^ 1)) {
return *z; // Nullptr deref FP? Now it's eliminated.
  }
  return 0;
}
```

Notice, that the FP is only eliminated in C++ mode, and still present in C mode 
for some reason.
My theory is that we use `int` as a `bool` type, thus simplification can't 
exploit that a boolean expression can only be `1` or `0`; and fails to simplify 
the expression.

The reason for having a wider impact than originally anticipated was that the 
function we modified `handleLValueBitCast()`
suggested that it should be invoked only for lvalue bitcasts, however, 
actually, it gets invoked from a few more places including ExprEngineC.cpp 
ExprEngine::VisitCast:
```C++
  case CK_IntegralToBoolean:
  case CK_IntegralToFloating:
  case CK_FloatingToIntegral:
  case CK_FloatingToBoolean:
  case CK_FloatingCast:
  case CK_FloatingRealToComplex:
  case CK_FloatingComplexToReal:
  case CK_FloatingComplexToBoolean:
  case CK_FloatingComplexCast:
  case CK_FloatingComplexToIntegralComplex:
  case CK_IntegralRealToComplex:
  case CK_IntegralComplexToReal:
  case CK_IntegralComplexToBoolean:
  case CK_IntegralComplexCast:
  case CK_IntegralComplexToFloatingComplex:
  case CK_CPointerToObjCPointerCast:
  case CK_BlockPointerToObjCPointerCast:
  case CK_AnyPointerToBlockPointerCast:
  case CK_ObjCObjectLValueCast:
  case CK_ZeroToOCLOpaqueType:
  case CK_IntToOCLSampler:
  case CK_LValueBitCast:
  case CK_FloatingToFixedPoint:
  case CK_FixedPointToFloating:
  case CK_FixedPointCast:
  case CK_FixedPointToBoolean:
  case CK_FixedPointToIntegral:
  case CK_IntegralToFixedPoint: {
state =
handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
continue;
  }
```

And this could have caused this "improvement".

---

The exploded node of the `PostStmt` `((x & 1) ^ 1)` was this prior the patch:
![image](https://github.com/llvm/llvm-project/assets/6280485/9fd6c577-c92d-48bc-a348-43014f7f3d41)
And now it looks like this (notice that the expression value is now simplified 
to `0 U1b`):
![image](https://github.com/llvm/llvm-project/assets/6280485/48c4cd9a-dc36-46ac-a871-67ebc5fd52f7)

Here is how a child node looks like for C now (notice that the constraint is 
`((reg_$0) & 1) ^ 1:  { [-2147483648, -1], [1, 2147483647] }`. This is 
the same state we had before this patch for C and C++ as well.
![image](https://github.com/llvm/llvm-project/assets/6280485/4335f96b-6c94-4bb0-96db-75e1f0474307)


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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

`auto-merge` might be disabled probably. I can't find the button mentioned 
[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request).

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

Fixed and resubmited #66498

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

steakhal wrote:

I thought "Mergeing" would wait and confirm if the checks pass, and only merge 
it if they succeed. Apparently, it's not the case here xD

The tests now break even on x86 linux. Could you please have a look? @danix800 

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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

Thanks!

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/66463

>From d48b57387e3dc1c2f3fdeae00fe1596b3466638d Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 15 Sep 2023 14:01:26 +0800
Subject: [PATCH] [analyzer] Simplify SVal for simple NonLoc->Loc casts

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |  3 ++-
 .../symbol-simplification-nonloc-loc.cpp  | 26 +++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());
diff --git a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp 
b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
index 485f68d9a5acfba..619fda824cb70b5 100644
--- a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
+++ b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
 // RUN:-triple x86_64-pc-linux-gnu -verify
 
+void clang_analyzer_eval(int);
+
 #define BINOP(OP) [](auto x, auto y) { return x OP y; }
 
 template 
@@ -73,3 +75,27 @@ void zoo1backwards() {
   *(0 + p) = nullptr;  // warn
   **(0 + p) = 'a'; // no-warning: this should be unreachable
 }
+
+void test_simplified_before_cast_add(long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

danix800 wrote:

Moved this into `symbol-simplification-nonloc-loc.cpp`.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;

danix800 wrote:

I'll move this into `symbol-simplification-nonloc-loc.cpp` which already 
restrict that target to be `x86_64`.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);

danix800 wrote:

Bound value might not be used at all, so I think lazy simplification would be 
better.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

https://github.com/steakhal commented:

I like it. Thanks!
This is pretty much good to go, but let's have a short discussion first.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);

steakhal wrote:

Did you try to simplify after the cast?
To me, it would make more sense to bind a simplified value.
However, I also know that casts are weird at best :D

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;

steakhal wrote:

I fear this statement assumes that `sizeof(int*)` is equal to `sizeof(long 
long)`, right?
If that's the case, we need to pin the target to ensure it's a valid assumption 
on all hosts.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

steakhal wrote:

I think I'd prefer to look for a place where similar things are tested and add 
these there.

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread via cfe-commits

llvmbot wrote:




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


Changes
NonLoc symbolic SVal to Loc casts are not supported except for 
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can go through 
nonloc::ConcreteInt->loc::ConcreteInt path. For example:

```c
  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }
```
If simplified, `t2` is 0, resulting `p` is nullptr, otherwise `p` is unknown.

Fixes #62232
--
Full diff: https://github.com/llvm/llvm-project/pull/66463.diff

2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp (+2-1) 
- (added) clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c (+31) 



diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state-gt;getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we#x27;re treating the boolean as a signed i1
   if (CastE-gt;getCastKind() == CK_BooleanToSignedIntegral 
amp;amp; V.isValid())
 V = svalBuilder.evalMinus(V.castAslt;NonLocgt;());
diff --git a/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c 
b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
new file mode 100644
index 000..db8b1456527e523
--- /dev/null
+++ b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}




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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

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

NonLoc symbolic SVal to Loc casts are not supported except for 
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can go through 
nonloc::ConcreteInt->loc::ConcreteInt path. For example:

```c
  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }
```
If simplified, `t2` is 0, resulting `p` is nullptr, otherwise `p` is unknown.

Fixes #62232

>From e171f8ea4d0fea12dadad6b0ecaffba42ff6ba85 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 15 Sep 2023 14:01:26 +0800
Subject: [PATCH] [analyzer] Simplify SVal for simple NonLoc->Loc casts

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |  3 +-
 ...solver-sym-simplification-lvalue-bitcast.c | 31 +++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());
diff --git a/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c 
b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
new file mode 100644
index 000..db8b1456527e523
--- /dev/null
+++ b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

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