Author: r.stahl Date: Tue May 29 07:14:22 2018 New Revision: 333417 URL: http://llvm.org/viewvc/llvm-project?rev=333417&view=rev Log: [analyzer] const init: handle non-explicit cases more accurately
Summary: If the access is out of bounds, return UndefinedVal. If it is missing an explicit init, return the implicit zero value it must have. Reviewers: NoQ, xazax.hun, george.karpenkov Reviewed By: NoQ Subscribers: szepet, rnkovacs, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D46823 Added: cfe/trunk/test/Analysis/initialization.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp cfe/trunk/test/Analysis/initialization.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=333417&r1=333416&r2=333417&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Tue May 29 07:14:22 2018 @@ -1638,9 +1638,18 @@ SVal RegionStoreManager::getBindingForEl // The array index has to be known. if (auto CI = R->getIndex().getAs<nonloc::ConcreteInt>()) { int64_t i = CI->getValue().getSExtValue(); - // Return unknown value if index is out of bounds. - if (i < 0 || i >= InitList->getNumInits()) - return UnknownVal(); + // If it is known that the index is out of bounds, we can return + // an undefined value. + if (i < 0) + return UndefinedVal(); + + if (auto CAT = Ctx.getAsConstantArrayType(VD->getType())) + if (CAT->getSize().sle(i)) + return UndefinedVal(); + + // If there is a list, but no init, it must be zero. + if (i >= InitList->getNumInits()) + return svalBuilder.makeZeroVal(R->getElementType()); if (const Expr *ElemInit = InitList->getInit(i)) if (Optional<SVal> V = svalBuilder.getConstantVal(ElemInit)) @@ -1715,11 +1724,15 @@ SVal RegionStoreManager::getBindingForFi // Either the record variable or the field has to be const qualified. if (RecordVarTy.isConstQualified() || Ty.isConstQualified()) if (const Expr *Init = VD->getInit()) - if (const auto *InitList = dyn_cast<InitListExpr>(Init)) - if (Index < InitList->getNumInits()) + if (const auto *InitList = dyn_cast<InitListExpr>(Init)) { + if (Index < InitList->getNumInits()) { if (const Expr *FieldInit = InitList->getInit(Index)) if (Optional<SVal> V = svalBuilder.getConstantVal(FieldInit)) return *V; + } else { + return svalBuilder.makeZeroVal(Ty); + } + } } return getBindingForFieldOrElementCommon(B, R, Ty); Modified: cfe/trunk/test/Analysis/initialization.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initialization.c?rev=333417&r1=333416&r2=333417&view=diff ============================================================================== --- cfe/trunk/test/Analysis/initialization.c (original) +++ cfe/trunk/test/Analysis/initialization.c Tue May 29 07:14:22 2018 @@ -1,7 +1,28 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); void initbug() { const union { float a; } u = {}; (void)u.a; // no-crash } + +int const parr[2] = {1}; +void constarr() { + int i = 2; + clang_analyzer_eval(parr[i]); // expected-warning{{UNDEFINED}} + i = 1; + clang_analyzer_eval(parr[i] == 0); // expected-warning{{TRUE}} + i = -1; + clang_analyzer_eval(parr[i]); // expected-warning{{UNDEFINED}} +} + +struct SM { + int a; + int b; +}; +const struct SM sm = {.a = 1}; +void multinit() { + clang_analyzer_eval(sm.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(sm.b == 0); // expected-warning{{TRUE}} +} Added: cfe/trunk/test/Analysis/initialization.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initialization.cpp?rev=333417&view=auto ============================================================================== --- cfe/trunk/test/Analysis/initialization.cpp (added) +++ cfe/trunk/test/Analysis/initialization.cpp Tue May 29 07:14:22 2018 @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); + +struct S { + int a = 3; +}; +S const sarr[2] = {}; +void definit() { + int i = 1; + // FIXME: Should recognize that it is 3. + clang_analyzer_eval(sarr[i].a); // expected-warning{{UNKNOWN}} +} + +int const arr[2][2] = {}; +void arr2init() { + int i = 1; + // FIXME: Should recognize that it is 0. + clang_analyzer_eval(arr[i][0]); // expected-warning{{UNKNOWN}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits