AnalysisBasedWarnings.cpp revision 7cd088e519d7e6caa4c4c12db52e0e4ae35d25c2
1//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines analysis_warnings::[Policy,Executor]. 11// Together they are used by Sema to issue warnings based on inexpensive 12// static analysis algorithms in libAnalysis. 13// 14//===----------------------------------------------------------------------===// 15 16#include "clang/Sema/Sema.h" 17#include "clang/Sema/AnalysisBasedWarnings.h" 18#include "clang/Basic/SourceManager.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/ExprObjC.h" 21#include "clang/AST/ExprCXX.h" 22#include "clang/AST/StmtObjC.h" 23#include "clang/AST/StmtCXX.h" 24#include "clang/Analysis/AnalysisContext.h" 25#include "clang/Analysis/CFG.h" 26#include "clang/Analysis/Analyses/ReachableCode.h" 27#include "llvm/ADT/BitVector.h" 28#include "llvm/Support/Casting.h" 29 30using namespace clang; 31 32//===----------------------------------------------------------------------===// 33// Unreachable code analysis. 34//===----------------------------------------------------------------------===// 35 36namespace { 37 class UnreachableCodeHandler : public reachable_code::Callback { 38 Sema &S; 39 public: 40 UnreachableCodeHandler(Sema &s) : S(s) {} 41 42 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 43 S.Diag(L, diag::warn_unreachable) << R1 << R2; 44 } 45 }; 46} 47 48/// CheckUnreachable - Check for unreachable code. 49static void CheckUnreachable(Sema &S, AnalysisContext &AC) { 50 UnreachableCodeHandler UC(S); 51 reachable_code::FindUnreachableCode(AC, UC); 52} 53 54//===----------------------------------------------------------------------===// 55// Check for missing return value. 56//===----------------------------------------------------------------------===// 57 58enum ControlFlowKind { 59 UnknownFallThrough, 60 NeverFallThrough, 61 MaybeFallThrough, 62 AlwaysFallThrough, 63 NeverFallThroughOrReturn 64}; 65 66/// CheckFallThrough - Check that we don't fall off the end of a 67/// Statement that should return a value. 68/// 69/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 70/// MaybeFallThrough iff we might or might not fall off the end, 71/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 72/// return. We assume NeverFallThrough iff we never fall off the end of the 73/// statement but we may return. We assume that functions not marked noreturn 74/// will return. 75static ControlFlowKind CheckFallThrough(AnalysisContext &AC) { 76 CFG *cfg = AC.getCFG(); 77 if (cfg == 0) return UnknownFallThrough; 78 79 // The CFG leaves in dead things, and we don't want the dead code paths to 80 // confuse us, so we mark all live things first. 81 llvm::BitVector live(cfg->getNumBlockIDs()); 82 unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(), 83 live); 84 85 bool AddEHEdges = AC.getAddEHEdges(); 86 if (!AddEHEdges && count != cfg->getNumBlockIDs()) 87 // When there are things remaining dead, and we didn't add EH edges 88 // from CallExprs to the catch clauses, we have to go back and 89 // mark them as live. 90 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 91 CFGBlock &b = **I; 92 if (!live[b.getBlockID()]) { 93 if (b.pred_begin() == b.pred_end()) { 94 if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 95 // When not adding EH edges from calls, catch clauses 96 // can otherwise seem dead. Avoid noting them as dead. 97 count += reachable_code::ScanReachableFromBlock(b, live); 98 continue; 99 } 100 } 101 } 102 103 // Now we know what is live, we check the live precessors of the exit block 104 // and look for fall through paths, being careful to ignore normal returns, 105 // and exceptional paths. 106 bool HasLiveReturn = false; 107 bool HasFakeEdge = false; 108 bool HasPlainEdge = false; 109 bool HasAbnormalEdge = false; 110 for (CFGBlock::pred_iterator I=cfg->getExit().pred_begin(), 111 E = cfg->getExit().pred_end(); 112 I != E; 113 ++I) { 114 CFGBlock& B = **I; 115 if (!live[B.getBlockID()]) 116 continue; 117 if (B.size() == 0) { 118 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 119 HasAbnormalEdge = true; 120 continue; 121 } 122 123 // A labeled empty statement, or the entry block... 124 HasPlainEdge = true; 125 continue; 126 } 127 Stmt *S = B[B.size()-1]; 128 if (isa<ReturnStmt>(S)) { 129 HasLiveReturn = true; 130 continue; 131 } 132 if (isa<ObjCAtThrowStmt>(S)) { 133 HasFakeEdge = true; 134 continue; 135 } 136 if (isa<CXXThrowExpr>(S)) { 137 HasFakeEdge = true; 138 continue; 139 } 140 if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 141 if (AS->isMSAsm()) { 142 HasFakeEdge = true; 143 HasLiveReturn = true; 144 continue; 145 } 146 } 147 if (isa<CXXTryStmt>(S)) { 148 HasAbnormalEdge = true; 149 continue; 150 } 151 152 bool NoReturnEdge = false; 153 if (CallExpr *C = dyn_cast<CallExpr>(S)) { 154 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 155 == B.succ_end()) { 156 HasAbnormalEdge = true; 157 continue; 158 } 159 Expr *CEE = C->getCallee()->IgnoreParenCasts(); 160 if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { 161 NoReturnEdge = true; 162 HasFakeEdge = true; 163 } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 164 ValueDecl *VD = DRE->getDecl(); 165 if (VD->hasAttr<NoReturnAttr>()) { 166 NoReturnEdge = true; 167 HasFakeEdge = true; 168 } 169 } 170 } 171 // FIXME: Remove this hack once temporaries and their destructors are 172 // modeled correctly by the CFG. 173 if (CXXExprWithTemporaries *E = dyn_cast<CXXExprWithTemporaries>(S)) { 174 for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I) { 175 const FunctionDecl *FD = E->getTemporary(I)->getDestructor(); 176 if (FD->hasAttr<NoReturnAttr>() || 177 FD->getType()->getAs<FunctionType>()->getNoReturnAttr()) { 178 NoReturnEdge = true; 179 HasFakeEdge = true; 180 break; 181 } 182 } 183 } 184 // FIXME: Add noreturn message sends. 185 if (NoReturnEdge == false) 186 HasPlainEdge = true; 187 } 188 if (!HasPlainEdge) { 189 if (HasLiveReturn) 190 return NeverFallThrough; 191 return NeverFallThroughOrReturn; 192 } 193 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 194 return MaybeFallThrough; 195 // This says AlwaysFallThrough for calls to functions that are not marked 196 // noreturn, that don't return. If people would like this warning to be more 197 // accurate, such functions should be marked as noreturn. 198 return AlwaysFallThrough; 199} 200 201namespace { 202 203struct CheckFallThroughDiagnostics { 204 unsigned diag_MaybeFallThrough_HasNoReturn; 205 unsigned diag_MaybeFallThrough_ReturnsNonVoid; 206 unsigned diag_AlwaysFallThrough_HasNoReturn; 207 unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 208 unsigned diag_NeverFallThroughOrReturn; 209 bool funMode; 210 211 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 212 CheckFallThroughDiagnostics D; 213 D.diag_MaybeFallThrough_HasNoReturn = 214 diag::warn_falloff_noreturn_function; 215 D.diag_MaybeFallThrough_ReturnsNonVoid = 216 diag::warn_maybe_falloff_nonvoid_function; 217 D.diag_AlwaysFallThrough_HasNoReturn = 218 diag::warn_falloff_noreturn_function; 219 D.diag_AlwaysFallThrough_ReturnsNonVoid = 220 diag::warn_falloff_nonvoid_function; 221 222 // Don't suggest that virtual functions be marked "noreturn", since they 223 // might be overridden by non-noreturn functions. 224 bool isVirtualMethod = false; 225 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 226 isVirtualMethod = Method->isVirtual(); 227 228 if (!isVirtualMethod) 229 D.diag_NeverFallThroughOrReturn = 230 diag::warn_suggest_noreturn_function; 231 else 232 D.diag_NeverFallThroughOrReturn = 0; 233 234 D.funMode = true; 235 return D; 236 } 237 238 static CheckFallThroughDiagnostics MakeForBlock() { 239 CheckFallThroughDiagnostics D; 240 D.diag_MaybeFallThrough_HasNoReturn = 241 diag::err_noreturn_block_has_return_expr; 242 D.diag_MaybeFallThrough_ReturnsNonVoid = 243 diag::err_maybe_falloff_nonvoid_block; 244 D.diag_AlwaysFallThrough_HasNoReturn = 245 diag::err_noreturn_block_has_return_expr; 246 D.diag_AlwaysFallThrough_ReturnsNonVoid = 247 diag::err_falloff_nonvoid_block; 248 D.diag_NeverFallThroughOrReturn = 249 diag::warn_suggest_noreturn_block; 250 D.funMode = false; 251 return D; 252 } 253 254 bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, 255 bool HasNoReturn) const { 256 if (funMode) { 257 return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function) 258 == Diagnostic::Ignored || ReturnsVoid) 259 && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr) 260 == Diagnostic::Ignored || !HasNoReturn) 261 && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) 262 == Diagnostic::Ignored || !ReturnsVoid); 263 } 264 265 // For blocks. 266 return ReturnsVoid && !HasNoReturn 267 && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) 268 == Diagnostic::Ignored || !ReturnsVoid); 269 } 270}; 271 272} 273 274/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 275/// function that should return a value. Check that we don't fall off the end 276/// of a noreturn function. We assume that functions and blocks not marked 277/// noreturn will return. 278static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 279 QualType BlockTy, 280 const CheckFallThroughDiagnostics& CD, 281 AnalysisContext &AC) { 282 283 bool ReturnsVoid = false; 284 bool HasNoReturn = false; 285 286 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 287 ReturnsVoid = FD->getResultType()->isVoidType(); 288 HasNoReturn = FD->hasAttr<NoReturnAttr>() || 289 FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 290 } 291 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 292 ReturnsVoid = MD->getResultType()->isVoidType(); 293 HasNoReturn = MD->hasAttr<NoReturnAttr>(); 294 } 295 else if (isa<BlockDecl>(D)) { 296 if (const FunctionType *FT = 297 BlockTy->getPointeeType()->getAs<FunctionType>()) { 298 if (FT->getResultType()->isVoidType()) 299 ReturnsVoid = true; 300 if (FT->getNoReturnAttr()) 301 HasNoReturn = true; 302 } 303 } 304 305 Diagnostic &Diags = S.getDiagnostics(); 306 307 // Short circuit for compilation speed. 308 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 309 return; 310 311 // FIXME: Function try block 312 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 313 switch (CheckFallThrough(AC)) { 314 case UnknownFallThrough: 315 break; 316 317 case MaybeFallThrough: 318 if (HasNoReturn) 319 S.Diag(Compound->getRBracLoc(), 320 CD.diag_MaybeFallThrough_HasNoReturn); 321 else if (!ReturnsVoid) 322 S.Diag(Compound->getRBracLoc(), 323 CD.diag_MaybeFallThrough_ReturnsNonVoid); 324 break; 325 case AlwaysFallThrough: 326 if (HasNoReturn) 327 S.Diag(Compound->getRBracLoc(), 328 CD.diag_AlwaysFallThrough_HasNoReturn); 329 else if (!ReturnsVoid) 330 S.Diag(Compound->getRBracLoc(), 331 CD.diag_AlwaysFallThrough_ReturnsNonVoid); 332 break; 333 case NeverFallThroughOrReturn: 334 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) 335 S.Diag(Compound->getLBracLoc(), 336 CD.diag_NeverFallThroughOrReturn); 337 break; 338 case NeverFallThrough: 339 break; 340 } 341 } 342} 343 344//===----------------------------------------------------------------------===// 345// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 346// warnings on a function, method, or block. 347//===----------------------------------------------------------------------===// 348 349clang::sema::AnalysisBasedWarnings::Policy::Policy() { 350 enableCheckFallThrough = 1; 351 enableCheckUnreachable = 0; 352} 353 354clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { 355 Diagnostic &D = S.getDiagnostics(); 356 DefaultPolicy.enableCheckUnreachable = (unsigned) 357 (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored); 358} 359 360void clang::sema:: 361AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 362 const Decl *D, QualType BlockTy) { 363 364 assert(BlockTy.isNull() || isa<BlockDecl>(D)); 365 366 // We avoid doing analysis-based warnings when there are errors for 367 // two reasons: 368 // (1) The CFGs often can't be constructed (if the body is invalid), so 369 // don't bother trying. 370 // (2) The code already has problems; running the analysis just takes more 371 // time. 372 Diagnostic &Diags = S.getDiagnostics(); 373 374 if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 375 return; 376 377 // Do not do any analysis for declarations in system headers if we are 378 // going to just ignore them. 379 if (Diags.getSuppressSystemWarnings() && 380 S.SourceMgr.isInSystemHeader(D->getLocation())) 381 return; 382 383 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 384 // For function templates, class templates and member function templates 385 // we'll do the analysis at instantiation time. 386 if (FD->isDependentContext()) 387 return; 388 } 389 390 const Stmt *Body = D->getBody(); 391 assert(Body); 392 393 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 394 // explosion for destrutors that can result and the compile time hit. 395 AnalysisContext AC(D, 0, false); 396 397 // Warning: check missing 'return' 398 if (P.enableCheckFallThrough) { 399 const CheckFallThroughDiagnostics &CD = 400 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 401 : CheckFallThroughDiagnostics::MakeForFunction(D)); 402 CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC); 403 } 404 405 // Warning: check for unreachable code 406 if (P.enableCheckUnreachable) 407 CheckUnreachable(S, AC); 408} 409