AnalysisBasedWarnings.cpp revision 94b1b4d785bc0f09f6af4be394e59d51f35dda60
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/AnalysisBasedWarnings.h" 17#include "clang/Sema/SemaInternal.h" 18#include "clang/Basic/SourceManager.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/DeclCXX.h" 21#include "clang/AST/ExprObjC.h" 22#include "clang/AST/ExprCXX.h" 23#include "clang/AST/StmtObjC.h" 24#include "clang/AST/StmtCXX.h" 25#include "clang/Analysis/AnalysisContext.h" 26#include "clang/Analysis/CFG.h" 27#include "clang/Analysis/Analyses/ReachableCode.h" 28#include "clang/Analysis/Analyses/UninitializedValuesV2.h" 29#include "llvm/ADT/BitVector.h" 30#include "llvm/Support/Casting.h" 31 32using namespace clang; 33 34//===----------------------------------------------------------------------===// 35// Unreachable code analysis. 36//===----------------------------------------------------------------------===// 37 38namespace { 39 class UnreachableCodeHandler : public reachable_code::Callback { 40 Sema &S; 41 public: 42 UnreachableCodeHandler(Sema &s) : S(s) {} 43 44 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 45 S.Diag(L, diag::warn_unreachable) << R1 << R2; 46 } 47 }; 48} 49 50/// CheckUnreachable - Check for unreachable code. 51static void CheckUnreachable(Sema &S, AnalysisContext &AC) { 52 UnreachableCodeHandler UC(S); 53 reachable_code::FindUnreachableCode(AC, UC); 54} 55 56//===----------------------------------------------------------------------===// 57// Check for missing return value. 58//===----------------------------------------------------------------------===// 59 60enum ControlFlowKind { 61 UnknownFallThrough, 62 NeverFallThrough, 63 MaybeFallThrough, 64 AlwaysFallThrough, 65 NeverFallThroughOrReturn 66}; 67 68/// CheckFallThrough - Check that we don't fall off the end of a 69/// Statement that should return a value. 70/// 71/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 72/// MaybeFallThrough iff we might or might not fall off the end, 73/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 74/// return. We assume NeverFallThrough iff we never fall off the end of the 75/// statement but we may return. We assume that functions not marked noreturn 76/// will return. 77static ControlFlowKind CheckFallThrough(AnalysisContext &AC) { 78 CFG *cfg = AC.getCFG(); 79 if (cfg == 0) return UnknownFallThrough; 80 81 // The CFG leaves in dead things, and we don't want the dead code paths to 82 // confuse us, so we mark all live things first. 83 llvm::BitVector live(cfg->getNumBlockIDs()); 84 unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(), 85 live); 86 87 bool AddEHEdges = AC.getAddEHEdges(); 88 if (!AddEHEdges && count != cfg->getNumBlockIDs()) 89 // When there are things remaining dead, and we didn't add EH edges 90 // from CallExprs to the catch clauses, we have to go back and 91 // mark them as live. 92 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 93 CFGBlock &b = **I; 94 if (!live[b.getBlockID()]) { 95 if (b.pred_begin() == b.pred_end()) { 96 if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 97 // When not adding EH edges from calls, catch clauses 98 // can otherwise seem dead. Avoid noting them as dead. 99 count += reachable_code::ScanReachableFromBlock(b, live); 100 continue; 101 } 102 } 103 } 104 105 // Now we know what is live, we check the live precessors of the exit block 106 // and look for fall through paths, being careful to ignore normal returns, 107 // and exceptional paths. 108 bool HasLiveReturn = false; 109 bool HasFakeEdge = false; 110 bool HasPlainEdge = false; 111 bool HasAbnormalEdge = false; 112 113 // Ignore default cases that aren't likely to be reachable because all 114 // enums in a switch(X) have explicit case statements. 115 CFGBlock::FilterOptions FO; 116 FO.IgnoreDefaultsWithCoveredEnums = 1; 117 118 for (CFGBlock::filtered_pred_iterator 119 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 120 const CFGBlock& B = **I; 121 if (!live[B.getBlockID()]) 122 continue; 123 if (B.size() == 0) { 124 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 125 HasAbnormalEdge = true; 126 continue; 127 } 128 129 // A labeled empty statement, or the entry block... 130 HasPlainEdge = true; 131 continue; 132 } 133 CFGElement CE = B[B.size()-1]; 134 if (CFGInitializer CI = CE.getAs<CFGInitializer>()) { 135 // A base or member initializer. 136 HasPlainEdge = true; 137 continue; 138 } 139 if (CFGMemberDtor MD = CE.getAs<CFGMemberDtor>()) { 140 // A member destructor. 141 HasPlainEdge = true; 142 continue; 143 } 144 if (CFGBaseDtor BD = CE.getAs<CFGBaseDtor>()) { 145 // A base destructor. 146 HasPlainEdge = true; 147 continue; 148 } 149 CFGStmt CS = CE.getAs<CFGStmt>(); 150 if (!CS.isValid()) 151 continue; 152 Stmt *S = CS.getStmt(); 153 if (isa<ReturnStmt>(S)) { 154 HasLiveReturn = true; 155 continue; 156 } 157 if (isa<ObjCAtThrowStmt>(S)) { 158 HasFakeEdge = true; 159 continue; 160 } 161 if (isa<CXXThrowExpr>(S)) { 162 HasFakeEdge = true; 163 continue; 164 } 165 if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 166 if (AS->isMSAsm()) { 167 HasFakeEdge = true; 168 HasLiveReturn = true; 169 continue; 170 } 171 } 172 if (isa<CXXTryStmt>(S)) { 173 HasAbnormalEdge = true; 174 continue; 175 } 176 177 bool NoReturnEdge = false; 178 if (CallExpr *C = dyn_cast<CallExpr>(S)) { 179 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 180 == B.succ_end()) { 181 HasAbnormalEdge = true; 182 continue; 183 } 184 Expr *CEE = C->getCallee()->IgnoreParenCasts(); 185 if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { 186 NoReturnEdge = true; 187 HasFakeEdge = true; 188 } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 189 ValueDecl *VD = DRE->getDecl(); 190 if (VD->hasAttr<NoReturnAttr>()) { 191 NoReturnEdge = true; 192 HasFakeEdge = true; 193 } 194 } 195 } 196 // FIXME: Add noreturn message sends. 197 if (NoReturnEdge == false) 198 HasPlainEdge = true; 199 } 200 if (!HasPlainEdge) { 201 if (HasLiveReturn) 202 return NeverFallThrough; 203 return NeverFallThroughOrReturn; 204 } 205 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 206 return MaybeFallThrough; 207 // This says AlwaysFallThrough for calls to functions that are not marked 208 // noreturn, that don't return. If people would like this warning to be more 209 // accurate, such functions should be marked as noreturn. 210 return AlwaysFallThrough; 211} 212 213namespace { 214 215struct CheckFallThroughDiagnostics { 216 unsigned diag_MaybeFallThrough_HasNoReturn; 217 unsigned diag_MaybeFallThrough_ReturnsNonVoid; 218 unsigned diag_AlwaysFallThrough_HasNoReturn; 219 unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 220 unsigned diag_NeverFallThroughOrReturn; 221 bool funMode; 222 SourceLocation FuncLoc; 223 224 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 225 CheckFallThroughDiagnostics D; 226 D.FuncLoc = Func->getLocation(); 227 D.diag_MaybeFallThrough_HasNoReturn = 228 diag::warn_falloff_noreturn_function; 229 D.diag_MaybeFallThrough_ReturnsNonVoid = 230 diag::warn_maybe_falloff_nonvoid_function; 231 D.diag_AlwaysFallThrough_HasNoReturn = 232 diag::warn_falloff_noreturn_function; 233 D.diag_AlwaysFallThrough_ReturnsNonVoid = 234 diag::warn_falloff_nonvoid_function; 235 236 // Don't suggest that virtual functions be marked "noreturn", since they 237 // might be overridden by non-noreturn functions. 238 bool isVirtualMethod = false; 239 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 240 isVirtualMethod = Method->isVirtual(); 241 242 if (!isVirtualMethod) 243 D.diag_NeverFallThroughOrReturn = 244 diag::warn_suggest_noreturn_function; 245 else 246 D.diag_NeverFallThroughOrReturn = 0; 247 248 D.funMode = true; 249 return D; 250 } 251 252 static CheckFallThroughDiagnostics MakeForBlock() { 253 CheckFallThroughDiagnostics D; 254 D.diag_MaybeFallThrough_HasNoReturn = 255 diag::err_noreturn_block_has_return_expr; 256 D.diag_MaybeFallThrough_ReturnsNonVoid = 257 diag::err_maybe_falloff_nonvoid_block; 258 D.diag_AlwaysFallThrough_HasNoReturn = 259 diag::err_noreturn_block_has_return_expr; 260 D.diag_AlwaysFallThrough_ReturnsNonVoid = 261 diag::err_falloff_nonvoid_block; 262 D.diag_NeverFallThroughOrReturn = 263 diag::warn_suggest_noreturn_block; 264 D.funMode = false; 265 return D; 266 } 267 268 bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, 269 bool HasNoReturn) const { 270 if (funMode) { 271 return (ReturnsVoid || 272 D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 273 FuncLoc) == Diagnostic::Ignored) 274 && (!HasNoReturn || 275 D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 276 FuncLoc) == Diagnostic::Ignored) 277 && (!ReturnsVoid || 278 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 279 == Diagnostic::Ignored); 280 } 281 282 // For blocks. 283 return ReturnsVoid && !HasNoReturn 284 && (!ReturnsVoid || 285 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 286 == Diagnostic::Ignored); 287 } 288}; 289 290} 291 292/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 293/// function that should return a value. Check that we don't fall off the end 294/// of a noreturn function. We assume that functions and blocks not marked 295/// noreturn will return. 296static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 297 QualType BlockTy, 298 const CheckFallThroughDiagnostics& CD, 299 AnalysisContext &AC) { 300 301 bool ReturnsVoid = false; 302 bool HasNoReturn = false; 303 304 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 305 ReturnsVoid = FD->getResultType()->isVoidType(); 306 HasNoReturn = FD->hasAttr<NoReturnAttr>() || 307 FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 308 } 309 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 310 ReturnsVoid = MD->getResultType()->isVoidType(); 311 HasNoReturn = MD->hasAttr<NoReturnAttr>(); 312 } 313 else if (isa<BlockDecl>(D)) { 314 if (const FunctionType *FT = 315 BlockTy->getPointeeType()->getAs<FunctionType>()) { 316 if (FT->getResultType()->isVoidType()) 317 ReturnsVoid = true; 318 if (FT->getNoReturnAttr()) 319 HasNoReturn = true; 320 } 321 } 322 323 Diagnostic &Diags = S.getDiagnostics(); 324 325 // Short circuit for compilation speed. 326 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 327 return; 328 329 // FIXME: Function try block 330 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 331 switch (CheckFallThrough(AC)) { 332 case UnknownFallThrough: 333 break; 334 335 case MaybeFallThrough: 336 if (HasNoReturn) 337 S.Diag(Compound->getRBracLoc(), 338 CD.diag_MaybeFallThrough_HasNoReturn); 339 else if (!ReturnsVoid) 340 S.Diag(Compound->getRBracLoc(), 341 CD.diag_MaybeFallThrough_ReturnsNonVoid); 342 break; 343 case AlwaysFallThrough: 344 if (HasNoReturn) 345 S.Diag(Compound->getRBracLoc(), 346 CD.diag_AlwaysFallThrough_HasNoReturn); 347 else if (!ReturnsVoid) 348 S.Diag(Compound->getRBracLoc(), 349 CD.diag_AlwaysFallThrough_ReturnsNonVoid); 350 break; 351 case NeverFallThroughOrReturn: 352 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) 353 S.Diag(Compound->getLBracLoc(), 354 CD.diag_NeverFallThroughOrReturn); 355 break; 356 case NeverFallThrough: 357 break; 358 } 359 } 360} 361 362//===----------------------------------------------------------------------===// 363// -Wuninitialized 364//===----------------------------------------------------------------------===// 365 366namespace { 367struct SLocSort { 368 bool operator()(const DeclRefExpr *a, const DeclRefExpr *b) { 369 SourceLocation aLoc = a->getLocStart(); 370 SourceLocation bLoc = b->getLocStart(); 371 return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 372 } 373}; 374 375class UninitValsDiagReporter : public UninitVariablesHandler { 376 Sema &S; 377 typedef llvm::SmallVector<const DeclRefExpr *, 2> UsesVec; 378 typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap; 379 UsesMap *uses; 380 381public: 382 UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 383 ~UninitValsDiagReporter() { 384 flushDiagnostics(); 385 } 386 387 void handleUseOfUninitVariable(const DeclRefExpr *dr, const VarDecl *vd) { 388 if (!uses) 389 uses = new UsesMap(); 390 391 UsesVec *&vec = (*uses)[vd]; 392 if (!vec) 393 vec = new UsesVec(); 394 395 vec->push_back(dr); 396 } 397 398 void flushDiagnostics() { 399 if (!uses) 400 return; 401 402 for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 403 const VarDecl *vd = i->first; 404 UsesVec *vec = i->second; 405 406 S.Diag(vd->getLocStart(), diag::warn_var_is_uninit) 407 << vd->getDeclName() << vd->getSourceRange(); 408 409 // Sort the uses by their SourceLocations. While not strictly 410 // guaranteed to produce them in line/column order, this will provide 411 // a stable ordering. 412 std::sort(vec->begin(), vec->end(), SLocSort()); 413 414 for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) 415 { 416 const DeclRefExpr *dr = *vi; 417 S.Diag(dr->getLocStart(), diag::note_var_is_uninit) 418 << vd->getDeclName() << dr->getSourceRange(); 419 } 420 delete vec; 421 } 422 delete uses; 423 } 424}; 425} 426 427//===----------------------------------------------------------------------===// 428// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 429// warnings on a function, method, or block. 430//===----------------------------------------------------------------------===// 431 432clang::sema::AnalysisBasedWarnings::Policy::Policy() { 433 enableCheckFallThrough = 1; 434 enableCheckUnreachable = 0; 435} 436 437clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { 438 Diagnostic &D = S.getDiagnostics(); 439 DefaultPolicy.enableCheckUnreachable = (unsigned) 440 (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 441 Diagnostic::Ignored); 442} 443 444void clang::sema:: 445AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 446 const Decl *D, QualType BlockTy) { 447 448 assert(BlockTy.isNull() || isa<BlockDecl>(D)); 449 450 // We avoid doing analysis-based warnings when there are errors for 451 // two reasons: 452 // (1) The CFGs often can't be constructed (if the body is invalid), so 453 // don't bother trying. 454 // (2) The code already has problems; running the analysis just takes more 455 // time. 456 Diagnostic &Diags = S.getDiagnostics(); 457 458 if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 459 return; 460 461 // Do not do any analysis for declarations in system headers if we are 462 // going to just ignore them. 463 if (Diags.getSuppressSystemWarnings() && 464 S.SourceMgr.isInSystemHeader(D->getLocation())) 465 return; 466 467 // For code in dependent contexts, we'll do this at instantiation time. 468 if (cast<DeclContext>(D)->isDependentContext()) 469 return; 470 471 const Stmt *Body = D->getBody(); 472 assert(Body); 473 474 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 475 // explosion for destrutors that can result and the compile time hit. 476 AnalysisContext AC(D, 0, /*useUnoptimizedCFG=*/false, /*addehedges=*/false, 477 /*addImplicitDtors=*/true, /*addInitializers=*/true); 478 479 // Warning: check missing 'return' 480 if (P.enableCheckFallThrough) { 481 const CheckFallThroughDiagnostics &CD = 482 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 483 : CheckFallThroughDiagnostics::MakeForFunction(D)); 484 CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC); 485 } 486 487 // Warning: check for unreachable code 488 if (P.enableCheckUnreachable) 489 CheckUnreachable(S, AC); 490 491 if (Diags.getDiagnosticLevel(diag::warn_var_is_uninit, D->getLocStart()) 492 != Diagnostic::Ignored) { 493 if (CFG *cfg = AC.getCFG()) { 494 UninitValsDiagReporter reporter(S); 495 runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, reporter); 496 } 497 } 498} 499 500void clang::sema:: 501AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 502 const BlockExpr *E) { 503 return IssueWarnings(P, E->getBlockDecl(), E->getType()); 504} 505 506void clang::sema:: 507AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 508 const ObjCMethodDecl *D) { 509 return IssueWarnings(P, D, QualType()); 510} 511 512void clang::sema:: 513AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 514 const FunctionDecl *D) { 515 return IssueWarnings(P, D, QualType()); 516} 517