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