[analyzer][solver] Handle UnarySymExpr in SMTConv

Dependent patch adds UnarySymExpr, now I'd like to handle that for SMT
conversions like refutation.

Differential Revision: https://reviews.llvm.org/D125547
This commit is contained in:
Gabor Marton 2022-05-13 15:52:48 +02:00
parent 88abc50398
commit cd5783d3e8
3 changed files with 69 additions and 0 deletions

View File

@ -446,6 +446,28 @@ public:
return getCastExpr(Solver, Ctx, Exp, FromTy, Sym->getType());
}
if (const UnarySymExpr *USE = dyn_cast<UnarySymExpr>(Sym)) {
if (RetTy)
*RetTy = Sym->getType();
QualType OperandTy;
llvm::SMTExprRef OperandExp =
getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);
llvm::SMTExprRef UnaryExp =
fromUnOp(Solver, USE->getOpcode(), OperandExp);
// Currently, without the `support-symbolic-integer-casts=true` option,
// we do not emit `SymbolCast`s for implicit casts.
// One such implicit cast is missing if the operand of the unary operator
// has a different type than the unary itself.
if (Ctx.getTypeSize(OperandTy) != Ctx.getTypeSize(Sym->getType())) {
if (hasComparison)
*hasComparison = false;
return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, Sym->getType());
}
return UnaryExp;
}
if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
llvm::SMTExprRef Exp =
getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy);

View File

@ -0,0 +1,33 @@
// RUN: %clang_analyze_cc1 %s \
// RUN: -analyzer-checker=core,debug.ExprInspection \
// RUN: -analyzer-config eagerly-assume=true \
// RUN: -verify
// RUN: %clang_analyze_cc1 %s \
// RUN: -analyzer-checker=core,debug.ExprInspection \
// RUN: -analyzer-config eagerly-assume=true \
// RUN: -analyzer-config support-symbolic-integer-casts=true \
// RUN: -verify
// RUN: %clang_analyze_cc1 %s \
// RUN: -analyzer-checker=core,debug.ExprInspection \
// RUN: -analyzer-config eagerly-assume=true \
// RUN: -analyzer-config crosscheck-with-z3=true \
// RUN: -verify
// RUN: %clang_analyze_cc1 %s \
// RUN: -analyzer-checker=core,debug.ExprInspection \
// RUN: -analyzer-config eagerly-assume=true \
// RUN: -analyzer-config crosscheck-with-z3=true \
// RUN: -analyzer-config support-symbolic-integer-casts=true \
// RUN: -verify
// REQUIRES: z3
void k(long L) {
int g = L;
int h = g + 1;
int j;
j += -h < 0; // should not crash
// expected-warning@-1{{garbage}}
}

View File

@ -14,6 +14,20 @@ int foo(int x)
return 0;
}
int unary(int x, long l)
{
int *z = 0;
int y = l;
if ((x & 1) && ((x & 1) ^ 1))
if (-y)
#ifdef NO_CROSSCHECK
return *z; // expected-warning {{Dereference of null pointer (loaded from variable 'z')}}
#else
return *z; // no-warning
#endif
return 0;
}
void g(int d);
void f(int *a, int *b) {