Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,17 +456,15 @@ class SMTConv {
llvm::SMTExprRef OperandExp =
getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);

if (const BinarySymExpr *BSE =
dyn_cast<BinarySymExpr>(USE->getOperand())) {
if (USE->getOpcode() == UO_Minus &&
BinaryOperator::isComparisonOp(BSE->getOpcode()))
// The comparison operator yields a boolean value in the Z3
// language and applying the unary minus operator on a boolean
// crashes Z3. However, the unary minus does nothing in this
// context (a number is truthy if and only if its negative is
// truthy), so let's just ignore the unary minus.
// TODO: Replace this with a more general solution.
return OperandExp;
// When the operand is a bool expr, but the operator is an integeral
// operator, casting the bool expr to the integer before creating the
// unary operator.
// E.g. -(5 && a)
if (OperandTy == Ctx.BoolTy && OperandTy != *RetTy &&
(*RetTy)->isIntegerType()) {
OperandExp = fromCast(Solver, OperandExp, (*RetTy),
Ctx.getTypeSize(*RetTy), OperandTy, 1);
OperandTy = (*RetTy);
}

llvm::SMTExprRef UnaryExp =
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Analysis/z3-unarysymexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ int z3_crash2(int a) {
return *d; // expected-warning{{Dereference of undefined pointer value}}
return 0;
}

// Refer to issue 165779
void z3_crash3(long a) {
if (~-(5 && a)) {
long *c;
*c; // expected-warning{{Dereference of undefined pointer value (loaded from variable 'c')}}
}
}
Loading