1ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie//= UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-==// 2610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 3610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// The LLVM Compiler Infrastructure 4610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 5610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// This file is distributed under the University of Illinois Open Source 6610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// License. See LICENSE.TXT for details. 7610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 8610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 9610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 10610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// This file defines APIs for invoking and reported uninitialized values 11610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// warnings. 12610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 13610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 14610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 15610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#ifndef LLVM_CLANG_UNINIT_VALS_H 16610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#define LLVM_CLANG_UNINIT_VALS_H 17610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 189946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko#include "clang/AST/Stmt.h" 192815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith#include "llvm/ADT/SmallVector.h" 202815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 21610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace clang { 22610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 231d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext; 24ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikieclass CFG; 25610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass DeclContext; 26a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenekclass Expr; 27610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass VarDecl; 28ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 292815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith/// A use of a variable, which might be uninitialized. 302815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smithclass UninitUse { 312815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smithpublic: 322815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith struct Branch { 332815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const Stmt *Terminator; 342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith unsigned Output; 352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith }; 362815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 372815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smithprivate: 382815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// The expression which uses this variable. 392815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const Expr *User; 402815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 418a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// Is this use uninitialized whenever the function is called? 428a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith bool UninitAfterCall; 438a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 448a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// Is this use uninitialized whenever the variable declaration is reached? 458a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith bool UninitAfterDecl; 468a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// Does this use always see an uninitialized value? 482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith bool AlwaysUninit; 492815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 502815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// This use is always uninitialized if it occurs after any of these branches 512815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// is taken. 52cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<Branch, 2> UninitBranches; 532815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 542815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smithpublic: 558a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith UninitUse(const Expr *User, bool AlwaysUninit) 568a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith : User(User), UninitAfterCall(false), UninitAfterDecl(false), 578a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith AlwaysUninit(AlwaysUninit) {} 582815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 592815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith void addUninitBranch(Branch B) { 602815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith UninitBranches.push_back(B); 612815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 622815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 638a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith void setUninitAfterCall() { UninitAfterCall = true; } 648a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith void setUninitAfterDecl() { UninitAfterDecl = true; } 658a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 662815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// Get the expression containing the uninitialized use. 672815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const Expr *getUser() const { return User; } 682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 692815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// The kind of uninitialized use. 702815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith enum Kind { 712815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// The use might be uninitialized. 722815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Maybe, 732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// The use is uninitialized whenever a certain branch is taken. 742815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Sometimes, 758a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// The use is uninitialized the first time it is reached after we reach 768a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// the variable's declaration. 778a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith AfterDecl, 788a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// The use is uninitialized the first time it is reached after the function 798a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith /// is called. 808a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith AfterCall, 812815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// The use is always uninitialized. 822815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Always 832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith }; 842815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 852815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// Get the kind of uninitialized use. 862815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Kind getKind() const { 872815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith return AlwaysUninit ? Always : 888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith UninitAfterCall ? AfterCall : 898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith UninitAfterDecl ? AfterDecl : 902815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith !branch_empty() ? Sometimes : Maybe; 912815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 922815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 93cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko typedef SmallVectorImpl<Branch>::const_iterator branch_iterator; 942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /// Branches which inevitably result in the variable being used uninitialized. 952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith branch_iterator branch_begin() const { return UninitBranches.begin(); } 962815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith branch_iterator branch_end() const { return UninitBranches.end(); } 972815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith bool branch_empty() const { return UninitBranches.empty(); } 982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith}; 992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 100610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitVariablesHandler { 101610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 102610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek UninitVariablesHandler() {} 103610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek virtual ~UninitVariablesHandler(); 1049e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 1059e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek /// Called when the uninitialized variable is used at the given expression. 1062815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith virtual void handleUseOfUninitVariable(const VarDecl *vd, 1072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const UninitUse &use) {} 108ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1099e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek /// Called when the uninitialized variable analysis detects the 1109e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek /// idiom 'int x = x'. All other uses of 'x' within the initializer 1119e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek /// are handled by handleUseOfUninitVariable. 1129e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek virtual void handleSelfInit(const VarDecl *vd) {} 113610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 1145d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 1155d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthstruct UninitVariablesAnalysisStats { 1165d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned NumVariablesAnalyzed; 1175d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned NumBlockVisits; 1185d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth}; 1195d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 120610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg, 1211d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext &ac, 1225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth UninitVariablesHandler &handler, 1235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth UninitVariablesAnalysisStats &stats); 124610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 125610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 126610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#endif 127