diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h @@ -446,6 +446,14 @@ return getCastExpr(Solver, Ctx, Exp, FromTy, Sym->getType()); } + if (const UnarySymExpr *USE = dyn_cast(Sym)) { + if (RetTy) + *RetTy = Sym->getType(); + llvm::SMTExprRef Exp = + getSymExpr(Solver, Ctx, USE->getOperand(), nullptr, hasComparison); + return fromUnOp(Solver, USE->getOpcode(), Exp); + } + if (const BinarySymExpr *BSE = dyn_cast(Sym)) { llvm::SMTExprRef Exp = getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy); diff --git a/clang/test/Analysis/z3-crosscheck.c b/clang/test/Analysis/z3-crosscheck.c --- a/clang/test/Analysis/z3-crosscheck.c +++ b/clang/test/Analysis/z3-crosscheck.c @@ -14,6 +14,20 @@ 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) {