From ee49cd21c4f101034ea5457876b4bbd33d85c4d6 Mon Sep 17 00:00:00 2001 From: George Karpenkov Date: Wed, 29 Aug 2018 20:29:59 +0000 Subject: [PATCH] [analyzer] Resolve the crash in ReturnUndefChecker By making sure the returned value from getKnownSVal is consistent with the value used inside expression engine. PR38427 Differential Revision: https://reviews.llvm.org/D51252 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340965 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/UndefResultChecker.cpp | 1 + lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 1 + test/Analysis/casts.c | 25 +++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index bbf3215e4d..47faf699f9 100644 --- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -69,6 +69,7 @@ static bool isLeftShiftResultUnrepresentable(const BinaryOperator *B, ProgramStateRef State = C.getState(); const llvm::APSInt *LHS = SB.getKnownValue(State, C.getSVal(B->getLHS())); const llvm::APSInt *RHS = SB.getKnownValue(State, C.getSVal(B->getRHS())); + assert(LHS && RHS && "Values unknown, inconsistent state"); return (unsigned)RHS->getZExtValue() > LHS->countLeadingZeros(); } diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 00cf067d31..36a0f4e6d8 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -1201,6 +1201,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state, const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state, SVal V) { + V = simplifySVal(state, V); if (V.isUnknownOrUndef()) return nullptr; diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 938a6eb106..3e6a9e0595 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,5 +1,6 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-config eagerly-assume=false -verify %s -// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-config eagerly-assume=false -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -DEAGERLY_ASSUME=1 -w %s extern void clang_analyzer_eval(_Bool); @@ -16,6 +17,8 @@ struct sockaddr_storage {}; void getsockname(); +#ifndef EAGERLY_ASSUME + void f(int sock) { struct sockaddr_storage storage; struct sockaddr* sockaddr = (struct sockaddr*)&storage; // expected-warning{{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} @@ -188,3 +191,21 @@ void testSwitchWithSizeofs() { case sizeof(char):; // no-crash } } + +#endif + +#ifdef EAGERLY_ASSUME + +// expected-no-diagnostics + +int globalA; // TODO: the example is not representative. +extern int globalFunc(); +void no_crash_on_symsym_cast_to_long() { + char c = globalFunc() - 5; + c == 0; + globalA -= c; + globalA == 3; + (long)globalA << 48; // no-crash +} + +#endif -- 2.40.0