1b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek//===--- UndefinedAssignmentChecker.h ---------------------------*- C++ -*--==// 2b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// 3b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// The LLVM Compiler Infrastructure 4b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// 5b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// This file is distributed under the University of Illinois Open Source 6b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// License. See LICENSE.TXT for details. 7b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// 8b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek//===----------------------------------------------------------------------===// 9b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// 10267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis// This defines UndefinedAssignmentChecker, a builtin check in ExprEngine that 11b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// checks for assigning undefined values. 12b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek// 13b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek//===----------------------------------------------------------------------===// 14b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 15267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis#include "ClangSACheckers.h" 16ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 17267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 18267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 21b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenekusing namespace clang; 229ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 23b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 24c3372e0ee8dac4fc11c771a92b05e4641bce6b32Zhongxing Xunamespace { 25ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass UndefinedAssignmentChecker 26ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis : public Checker<check::Bind> { 276f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith mutable OwningPtr<BugType> BT; 28267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis 29c3372e0ee8dac4fc11c771a92b05e4641bce6b32Zhongxing Xupublic: 30390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks void checkBind(SVal location, SVal val, const Stmt *S, 31390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks CheckerContext &C) const; 32c3372e0ee8dac4fc11c771a92b05e4641bce6b32Zhongxing Xu}; 33c3372e0ee8dac4fc11c771a92b05e4641bce6b32Zhongxing Xu} 34c3372e0ee8dac4fc11c771a92b05e4641bce6b32Zhongxing Xu 35267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidisvoid UndefinedAssignmentChecker::checkBind(SVal location, SVal val, 36390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks const Stmt *StoreE, 37267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis CheckerContext &C) const { 38b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek if (!val.isUndef()) 39b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek return; 40b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 41d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek ExplodedNode *N = C.generateSink(); 42b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 43b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek if (!N) 44b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek return; 45b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 4612182a0344c11970f307bc79eeb102633561b680Ted Kremenek const char *str = "Assigned value is garbage or undefined"; 4712182a0344c11970f307bc79eeb102633561b680Ted Kremenek 48b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek if (!BT) 49267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis BT.reset(new BuiltinBug(str)); 50b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 51b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek // Generate a report for this bug. 5212182a0344c11970f307bc79eeb102633561b680Ted Kremenek const Expr *ex = 0; 53b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 5479d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek while (StoreE) { 5579d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) { 5612182a0344c11970f307bc79eeb102633561b680Ted Kremenek if (B->isCompoundAssignmentOp()) { 578bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = C.getState(); 585eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) { 5912182a0344c11970f307bc79eeb102633561b680Ted Kremenek str = "The left expression of the compound assignment is an " 6012182a0344c11970f307bc79eeb102633561b680Ted Kremenek "uninitialized value. The computed value will also be garbage"; 6112182a0344c11970f307bc79eeb102633561b680Ted Kremenek ex = B->getLHS(); 6212182a0344c11970f307bc79eeb102633561b680Ted Kremenek break; 6312182a0344c11970f307bc79eeb102633561b680Ted Kremenek } 6412182a0344c11970f307bc79eeb102633561b680Ted Kremenek } 6550ecd1536a2b70327e9eb2c2c2a652cde3dae365Ted Kremenek 6650ecd1536a2b70327e9eb2c2c2a652cde3dae365Ted Kremenek ex = B->getRHS(); 6712182a0344c11970f307bc79eeb102633561b680Ted Kremenek break; 6812182a0344c11970f307bc79eeb102633561b680Ted Kremenek } 6912182a0344c11970f307bc79eeb102633561b680Ted Kremenek 7079d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) { 719c378f705405d37f49795d5e915989de774fe11fTed Kremenek const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl()); 7250ecd1536a2b70327e9eb2c2c2a652cde3dae365Ted Kremenek ex = VD->getInit(); 7350ecd1536a2b70327e9eb2c2c2a652cde3dae365Ted Kremenek } 7412182a0344c11970f307bc79eeb102633561b680Ted Kremenek 7512182a0344c11970f307bc79eeb102633561b680Ted Kremenek break; 76b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek } 77b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 78e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks BugReport *R = new BugReport(*BT, str, N); 7912182a0344c11970f307bc79eeb102633561b680Ted Kremenek if (ex) { 8012182a0344c11970f307bc79eeb102633561b680Ted Kremenek R->addRange(ex->getSourceRange()); 81a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose bugreporter::trackNullOrUndefValue(N, ex, *R); 8212182a0344c11970f307bc79eeb102633561b680Ted Kremenek } 83b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek C.EmitReport(R); 8412182a0344c11970f307bc79eeb102633561b680Ted Kremenek} 85b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 86267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidisvoid ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) { 87267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis mgr.registerChecker<UndefinedAssignmentChecker>(); 88267aa5c93b1eecc1d6f2c65ed2ba1fe840a9d0fdArgyrios Kyrtzidis} 89