blob: bc25c0a55483285046fc280378994c476dcb42be [file] [log] [blame]
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001//=- 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
Douglas Gregore737f502010-08-12 20:07:10 +000016#include "clang/Sema/AnalysisBasedWarnings.h"
John McCall2d887082010-08-25 22:03:47 +000017#include "clang/Sema/SemaInternal.h"
Ted Kremenek351ba912011-02-23 01:52:04 +000018#include "clang/Sema/ScopeInfo.h"
Ted Kremenekd068aab2010-03-20 21:11:09 +000019#include "clang/Basic/SourceManager.h"
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +000020#include "clang/Basic/SourceLocation.h"
Ted Kremenekfbb178a2011-01-21 19:41:46 +000021#include "clang/Lex/Preprocessor.h"
Richard Smithbdb97ff2012-05-26 06:20:46 +000022#include "clang/Lex/Lexer.h"
John McCall7cd088e2010-08-24 07:21:54 +000023#include "clang/AST/DeclObjC.h"
John McCall384aff82010-08-25 07:42:41 +000024#include "clang/AST/DeclCXX.h"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000025#include "clang/AST/ExprObjC.h"
26#include "clang/AST/ExprCXX.h"
27#include "clang/AST/StmtObjC.h"
28#include "clang/AST/StmtCXX.h"
Ted Kremenek6f417152011-04-04 20:56:00 +000029#include "clang/AST/EvaluatedExprVisitor.h"
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000030#include "clang/AST/StmtVisitor.h"
Richard Smithe0d3b4c2012-05-03 18:27:39 +000031#include "clang/AST/RecursiveASTVisitor.h"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000032#include "clang/Analysis/AnalysisContext.h"
33#include "clang/Analysis/CFG.h"
34#include "clang/Analysis/Analyses/ReachableCode.h"
Ted Kremenek351ba912011-02-23 01:52:04 +000035#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
Caitlin Sadowski402aa062011-09-09 16:11:56 +000036#include "clang/Analysis/Analyses/ThreadSafety.h"
Ted Kremenek351ba912011-02-23 01:52:04 +000037#include "clang/Analysis/CFGStmtMap.h"
Ted Kremenek6f342132011-03-15 03:17:07 +000038#include "clang/Analysis/Analyses/UninitializedValues.h"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000039#include "llvm/ADT/BitVector.h"
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000040#include "llvm/ADT/FoldingSet.h"
41#include "llvm/ADT/ImmutableMap.h"
42#include "llvm/ADT/PostOrderIterator.h"
43#include "llvm/ADT/SmallVector.h"
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +000044#include "llvm/ADT/StringRef.h"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000045#include "llvm/Support/Casting.h"
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000046#include <algorithm>
Richard Smithe0d3b4c2012-05-03 18:27:39 +000047#include <iterator>
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000048#include <vector>
Richard Smithe0d3b4c2012-05-03 18:27:39 +000049#include <deque>
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000050
51using namespace clang;
52
53//===----------------------------------------------------------------------===//
54// Unreachable code analysis.
55//===----------------------------------------------------------------------===//
56
57namespace {
58 class UnreachableCodeHandler : public reachable_code::Callback {
59 Sema &S;
60 public:
61 UnreachableCodeHandler(Sema &s) : S(s) {}
62
63 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
64 S.Diag(L, diag::warn_unreachable) << R1 << R2;
65 }
66 };
67}
68
69/// CheckUnreachable - Check for unreachable code.
Ted Kremenek1d26f482011-10-24 01:32:45 +000070static void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000071 UnreachableCodeHandler UC(S);
72 reachable_code::FindUnreachableCode(AC, UC);
73}
74
75//===----------------------------------------------------------------------===//
76// Check for missing return value.
77//===----------------------------------------------------------------------===//
78
John McCall16565aa2010-05-16 09:34:11 +000079enum ControlFlowKind {
80 UnknownFallThrough,
81 NeverFallThrough,
82 MaybeFallThrough,
83 AlwaysFallThrough,
84 NeverFallThroughOrReturn
85};
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000086
87/// CheckFallThrough - Check that we don't fall off the end of a
88/// Statement that should return a value.
89///
Sylvestre Ledruf3477c12012-09-27 10:16:10 +000090/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
91/// MaybeFallThrough iff we might or might not fall off the end,
92/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
93/// return. We assume NeverFallThrough iff we never fall off the end of the
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000094/// statement but we may return. We assume that functions not marked noreturn
95/// will return.
Ted Kremenek1d26f482011-10-24 01:32:45 +000096static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000097 CFG *cfg = AC.getCFG();
John McCall16565aa2010-05-16 09:34:11 +000098 if (cfg == 0) return UnknownFallThrough;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000099
100 // The CFG leaves in dead things, and we don't want the dead code paths to
101 // confuse us, so we mark all live things first.
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000102 llvm::BitVector live(cfg->getNumBlockIDs());
Ted Kremenek0f3b4ca2011-08-23 23:05:11 +0000103 unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000104 live);
105
106 bool AddEHEdges = AC.getAddEHEdges();
107 if (!AddEHEdges && count != cfg->getNumBlockIDs())
108 // When there are things remaining dead, and we didn't add EH edges
109 // from CallExprs to the catch clauses, we have to go back and
110 // mark them as live.
111 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
112 CFGBlock &b = **I;
113 if (!live[b.getBlockID()]) {
114 if (b.pred_begin() == b.pred_end()) {
115 if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
116 // When not adding EH edges from calls, catch clauses
117 // can otherwise seem dead. Avoid noting them as dead.
Ted Kremenek0f3b4ca2011-08-23 23:05:11 +0000118 count += reachable_code::ScanReachableFromBlock(&b, live);
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000119 continue;
120 }
121 }
122 }
123
124 // Now we know what is live, we check the live precessors of the exit block
125 // and look for fall through paths, being careful to ignore normal returns,
126 // and exceptional paths.
127 bool HasLiveReturn = false;
128 bool HasFakeEdge = false;
129 bool HasPlainEdge = false;
130 bool HasAbnormalEdge = false;
Ted Kremenek90b828a2010-09-09 00:06:07 +0000131
132 // Ignore default cases that aren't likely to be reachable because all
133 // enums in a switch(X) have explicit case statements.
134 CFGBlock::FilterOptions FO;
135 FO.IgnoreDefaultsWithCoveredEnums = 1;
136
137 for (CFGBlock::filtered_pred_iterator
138 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
139 const CFGBlock& B = **I;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000140 if (!live[B.getBlockID()])
141 continue;
Ted Kremenek5811f592011-01-26 04:49:52 +0000142
Chandler Carruthe05ee6d2011-09-13 09:53:58 +0000143 // Skip blocks which contain an element marked as no-return. They don't
144 // represent actually viable edges into the exit block, so mark them as
145 // abnormal.
146 if (B.hasNoReturnElement()) {
147 HasAbnormalEdge = true;
148 continue;
149 }
150
Ted Kremenek5811f592011-01-26 04:49:52 +0000151 // Destructors can appear after the 'return' in the CFG. This is
152 // normal. We need to look pass the destructors for the return
153 // statement (if it exists).
154 CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
Ted Kremenekc9f8f5a2011-03-02 20:32:29 +0000155
Chandler Carruthe05ee6d2011-09-13 09:53:58 +0000156 for ( ; ri != re ; ++ri)
157 if (isa<CFGStmt>(*ri))
Ted Kremenek5811f592011-01-26 04:49:52 +0000158 break;
Chandler Carruthe05ee6d2011-09-13 09:53:58 +0000159
Ted Kremenek5811f592011-01-26 04:49:52 +0000160 // No more CFGElements in the block?
161 if (ri == re) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000162 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
163 HasAbnormalEdge = true;
164 continue;
165 }
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000166 // A labeled empty statement, or the entry block...
167 HasPlainEdge = true;
168 continue;
169 }
Ted Kremenekf39e6a32011-01-25 22:50:47 +0000170
Ted Kremenek5811f592011-01-26 04:49:52 +0000171 CFGStmt CS = cast<CFGStmt>(*ri);
Ted Kremenekf1d10d92011-08-23 23:05:04 +0000172 const Stmt *S = CS.getStmt();
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000173 if (isa<ReturnStmt>(S)) {
174 HasLiveReturn = true;
175 continue;
176 }
177 if (isa<ObjCAtThrowStmt>(S)) {
178 HasFakeEdge = true;
179 continue;
180 }
181 if (isa<CXXThrowExpr>(S)) {
182 HasFakeEdge = true;
183 continue;
184 }
Chad Rosier8cd64b42012-06-11 20:47:18 +0000185 if (isa<MSAsmStmt>(S)) {
186 // TODO: Verify this is correct.
187 HasFakeEdge = true;
188 HasLiveReturn = true;
189 continue;
190 }
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000191 if (isa<CXXTryStmt>(S)) {
192 HasAbnormalEdge = true;
193 continue;
194 }
Chandler Carruthe05ee6d2011-09-13 09:53:58 +0000195 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
196 == B.succ_end()) {
197 HasAbnormalEdge = true;
198 continue;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000199 }
Chandler Carruthe05ee6d2011-09-13 09:53:58 +0000200
201 HasPlainEdge = true;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000202 }
203 if (!HasPlainEdge) {
204 if (HasLiveReturn)
205 return NeverFallThrough;
206 return NeverFallThroughOrReturn;
207 }
208 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
209 return MaybeFallThrough;
210 // This says AlwaysFallThrough for calls to functions that are not marked
211 // noreturn, that don't return. If people would like this warning to be more
212 // accurate, such functions should be marked as noreturn.
213 return AlwaysFallThrough;
214}
215
Dan Gohman3c46e8d2010-07-26 21:25:24 +0000216namespace {
217
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000218struct CheckFallThroughDiagnostics {
219 unsigned diag_MaybeFallThrough_HasNoReturn;
220 unsigned diag_MaybeFallThrough_ReturnsNonVoid;
221 unsigned diag_AlwaysFallThrough_HasNoReturn;
222 unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
223 unsigned diag_NeverFallThroughOrReturn;
Douglas Gregor793cd1c2012-02-15 16:20:15 +0000224 enum { Function, Block, Lambda } funMode;
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000225 SourceLocation FuncLoc;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000226
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000227 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000228 CheckFallThroughDiagnostics D;
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000229 D.FuncLoc = Func->getLocation();
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000230 D.diag_MaybeFallThrough_HasNoReturn =
231 diag::warn_falloff_noreturn_function;
232 D.diag_MaybeFallThrough_ReturnsNonVoid =
233 diag::warn_maybe_falloff_nonvoid_function;
234 D.diag_AlwaysFallThrough_HasNoReturn =
235 diag::warn_falloff_noreturn_function;
236 D.diag_AlwaysFallThrough_ReturnsNonVoid =
237 diag::warn_falloff_nonvoid_function;
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000238
239 // Don't suggest that virtual functions be marked "noreturn", since they
240 // might be overridden by non-noreturn functions.
241 bool isVirtualMethod = false;
242 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
243 isVirtualMethod = Method->isVirtual();
244
Douglas Gregorfcdd2cb2011-10-10 18:15:57 +0000245 // Don't suggest that template instantiations be marked "noreturn"
246 bool isTemplateInstantiation = false;
Ted Kremenek75df4ee2011-12-01 00:59:17 +0000247 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
248 isTemplateInstantiation = Function->isTemplateInstantiation();
Douglas Gregorfcdd2cb2011-10-10 18:15:57 +0000249
250 if (!isVirtualMethod && !isTemplateInstantiation)
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000251 D.diag_NeverFallThroughOrReturn =
252 diag::warn_suggest_noreturn_function;
253 else
254 D.diag_NeverFallThroughOrReturn = 0;
255
Douglas Gregor793cd1c2012-02-15 16:20:15 +0000256 D.funMode = Function;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000257 return D;
258 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000259
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000260 static CheckFallThroughDiagnostics MakeForBlock() {
261 CheckFallThroughDiagnostics D;
262 D.diag_MaybeFallThrough_HasNoReturn =
263 diag::err_noreturn_block_has_return_expr;
264 D.diag_MaybeFallThrough_ReturnsNonVoid =
265 diag::err_maybe_falloff_nonvoid_block;
266 D.diag_AlwaysFallThrough_HasNoReturn =
267 diag::err_noreturn_block_has_return_expr;
268 D.diag_AlwaysFallThrough_ReturnsNonVoid =
269 diag::err_falloff_nonvoid_block;
270 D.diag_NeverFallThroughOrReturn =
271 diag::warn_suggest_noreturn_block;
Douglas Gregor793cd1c2012-02-15 16:20:15 +0000272 D.funMode = Block;
273 return D;
274 }
275
276 static CheckFallThroughDiagnostics MakeForLambda() {
277 CheckFallThroughDiagnostics D;
278 D.diag_MaybeFallThrough_HasNoReturn =
279 diag::err_noreturn_lambda_has_return_expr;
280 D.diag_MaybeFallThrough_ReturnsNonVoid =
281 diag::warn_maybe_falloff_nonvoid_lambda;
282 D.diag_AlwaysFallThrough_HasNoReturn =
283 diag::err_noreturn_lambda_has_return_expr;
284 D.diag_AlwaysFallThrough_ReturnsNonVoid =
285 diag::warn_falloff_nonvoid_lambda;
286 D.diag_NeverFallThroughOrReturn = 0;
287 D.funMode = Lambda;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000288 return D;
289 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000290
David Blaikied6471f72011-09-25 23:23:43 +0000291 bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000292 bool HasNoReturn) const {
Douglas Gregor793cd1c2012-02-15 16:20:15 +0000293 if (funMode == Function) {
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000294 return (ReturnsVoid ||
295 D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
David Blaikied6471f72011-09-25 23:23:43 +0000296 FuncLoc) == DiagnosticsEngine::Ignored)
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000297 && (!HasNoReturn ||
298 D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
David Blaikied6471f72011-09-25 23:23:43 +0000299 FuncLoc) == DiagnosticsEngine::Ignored)
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000300 && (!ReturnsVoid ||
301 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
David Blaikied6471f72011-09-25 23:23:43 +0000302 == DiagnosticsEngine::Ignored);
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000303 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000304
Douglas Gregor793cd1c2012-02-15 16:20:15 +0000305 // For blocks / lambdas.
306 return ReturnsVoid && !HasNoReturn
307 && ((funMode == Lambda) ||
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000308 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
David Blaikied6471f72011-09-25 23:23:43 +0000309 == DiagnosticsEngine::Ignored);
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000310 }
311};
312
Dan Gohman3c46e8d2010-07-26 21:25:24 +0000313}
314
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000315/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
316/// function that should return a value. Check that we don't fall off the end
317/// of a noreturn function. We assume that functions and blocks not marked
318/// noreturn will return.
319static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
Ted Kremenek3ed6fc02011-02-23 01:51:48 +0000320 const BlockExpr *blkExpr,
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000321 const CheckFallThroughDiagnostics& CD,
Ted Kremenek1d26f482011-10-24 01:32:45 +0000322 AnalysisDeclContext &AC) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000323
324 bool ReturnsVoid = false;
325 bool HasNoReturn = false;
326
327 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
328 ReturnsVoid = FD->getResultType()->isVoidType();
329 HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
Rafael Espindola264ba482010-03-30 20:24:48 +0000330 FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000331 }
332 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
333 ReturnsVoid = MD->getResultType()->isVoidType();
334 HasNoReturn = MD->hasAttr<NoReturnAttr>();
335 }
336 else if (isa<BlockDecl>(D)) {
Ted Kremenek3ed6fc02011-02-23 01:51:48 +0000337 QualType BlockTy = blkExpr->getType();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000338 if (const FunctionType *FT =
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000339 BlockTy->getPointeeType()->getAs<FunctionType>()) {
340 if (FT->getResultType()->isVoidType())
341 ReturnsVoid = true;
342 if (FT->getNoReturnAttr())
343 HasNoReturn = true;
344 }
345 }
346
David Blaikied6471f72011-09-25 23:23:43 +0000347 DiagnosticsEngine &Diags = S.getDiagnostics();
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000348
349 // Short circuit for compilation speed.
350 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
351 return;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000352
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000353 // FIXME: Function try block
354 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
355 switch (CheckFallThrough(AC)) {
John McCall16565aa2010-05-16 09:34:11 +0000356 case UnknownFallThrough:
357 break;
358
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000359 case MaybeFallThrough:
360 if (HasNoReturn)
361 S.Diag(Compound->getRBracLoc(),
362 CD.diag_MaybeFallThrough_HasNoReturn);
363 else if (!ReturnsVoid)
364 S.Diag(Compound->getRBracLoc(),
365 CD.diag_MaybeFallThrough_ReturnsNonVoid);
366 break;
367 case AlwaysFallThrough:
368 if (HasNoReturn)
369 S.Diag(Compound->getRBracLoc(),
370 CD.diag_AlwaysFallThrough_HasNoReturn);
371 else if (!ReturnsVoid)
372 S.Diag(Compound->getRBracLoc(),
373 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
374 break;
375 case NeverFallThroughOrReturn:
Chandler Carruthb0656ec2011-08-31 09:01:53 +0000376 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
377 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
378 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
Douglas Gregorb3321092011-09-10 00:56:20 +0000379 << 0 << FD;
380 } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
381 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
382 << 1 << MD;
Chandler Carruthb0656ec2011-08-31 09:01:53 +0000383 } else {
384 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn);
385 }
386 }
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000387 break;
388 case NeverFallThrough:
389 break;
390 }
391 }
392}
393
394//===----------------------------------------------------------------------===//
Ted Kremenek610068c2011-01-15 02:58:47 +0000395// -Wuninitialized
396//===----------------------------------------------------------------------===//
397
Ted Kremenek6f417152011-04-04 20:56:00 +0000398namespace {
Chandler Carruth9f649462011-04-05 06:48:00 +0000399/// ContainsReference - A visitor class to search for references to
400/// a particular declaration (the needle) within any evaluated component of an
401/// expression (recursively).
Ted Kremenek6f417152011-04-04 20:56:00 +0000402class ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
Chandler Carruth9f649462011-04-05 06:48:00 +0000403 bool FoundReference;
404 const DeclRefExpr *Needle;
405
Ted Kremenek6f417152011-04-04 20:56:00 +0000406public:
Chandler Carruth9f649462011-04-05 06:48:00 +0000407 ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
408 : EvaluatedExprVisitor<ContainsReference>(Context),
409 FoundReference(false), Needle(Needle) {}
410
411 void VisitExpr(Expr *E) {
Ted Kremenek6f417152011-04-04 20:56:00 +0000412 // Stop evaluating if we already have a reference.
Chandler Carruth9f649462011-04-05 06:48:00 +0000413 if (FoundReference)
Ted Kremenek6f417152011-04-04 20:56:00 +0000414 return;
Chandler Carruth9f649462011-04-05 06:48:00 +0000415
416 EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
Ted Kremenek6f417152011-04-04 20:56:00 +0000417 }
Chandler Carruth9f649462011-04-05 06:48:00 +0000418
419 void VisitDeclRefExpr(DeclRefExpr *E) {
420 if (E == Needle)
421 FoundReference = true;
422 else
423 EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
Ted Kremenek6f417152011-04-04 20:56:00 +0000424 }
Chandler Carruth9f649462011-04-05 06:48:00 +0000425
426 bool doesContainReference() const { return FoundReference; }
Ted Kremenek6f417152011-04-04 20:56:00 +0000427};
428}
429
David Blaikie4f4f3492011-09-10 05:35:08 +0000430static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
Fariborz Jahaniana34194f2012-03-08 00:22:50 +0000431 QualType VariableTy = VD->getType().getCanonicalType();
432 if (VariableTy->isBlockPointerType() &&
433 !VD->hasAttr<BlocksAttr>()) {
434 S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
435 << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
436 return true;
437 }
438
David Blaikie4f4f3492011-09-10 05:35:08 +0000439 // Don't issue a fixit if there is already an initializer.
440 if (VD->getInit())
441 return false;
Fariborz Jahaniana34194f2012-03-08 00:22:50 +0000442
David Blaikie4f4f3492011-09-10 05:35:08 +0000443 // Suggest possible initialization (if any).
David Blaikie2c0abf42012-04-30 18:27:22 +0000444 std::string Init = S.getFixItZeroInitializerForType(VariableTy);
445 if (Init.empty())
David Blaikie4f4f3492011-09-10 05:35:08 +0000446 return false;
Richard Trieu7b0a3e32012-05-03 01:09:59 +0000447
448 // Don't suggest a fixit inside macros.
449 if (VD->getLocEnd().isMacroID())
450 return false;
451
Richard Smith7984de32012-01-12 23:53:29 +0000452 SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
Fariborz Jahaniana34194f2012-03-08 00:22:50 +0000453
Richard Smith7984de32012-01-12 23:53:29 +0000454 S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
455 << FixItHint::CreateInsertion(Loc, Init);
456 return true;
David Blaikie4f4f3492011-09-10 05:35:08 +0000457}
458
Richard Smithbdb97ff2012-05-26 06:20:46 +0000459/// Create a fixit to remove an if-like statement, on the assumption that its
460/// condition is CondVal.
461static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
462 const Stmt *Else, bool CondVal,
463 FixItHint &Fixit1, FixItHint &Fixit2) {
464 if (CondVal) {
465 // If condition is always true, remove all but the 'then'.
466 Fixit1 = FixItHint::CreateRemoval(
467 CharSourceRange::getCharRange(If->getLocStart(),
468 Then->getLocStart()));
469 if (Else) {
470 SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken(
471 Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts());
472 Fixit2 = FixItHint::CreateRemoval(
473 SourceRange(ElseKwLoc, Else->getLocEnd()));
474 }
475 } else {
476 // If condition is always false, remove all but the 'else'.
477 if (Else)
478 Fixit1 = FixItHint::CreateRemoval(
479 CharSourceRange::getCharRange(If->getLocStart(),
480 Else->getLocStart()));
481 else
482 Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());
483 }
484}
485
486/// DiagUninitUse -- Helper function to produce a diagnostic for an
487/// uninitialized use of a variable.
488static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
489 bool IsCapturedByBlock) {
490 bool Diagnosed = false;
491
492 // Diagnose each branch which leads to a sometimes-uninitialized use.
Richard Smith2815e1a2012-05-25 02:17:09 +0000493 for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
494 I != E; ++I) {
Richard Smithbdb97ff2012-05-26 06:20:46 +0000495 assert(Use.getKind() == UninitUse::Sometimes);
496
497 const Expr *User = Use.getUser();
Richard Smith2815e1a2012-05-25 02:17:09 +0000498 const Stmt *Term = I->Terminator;
Richard Smithbdb97ff2012-05-26 06:20:46 +0000499
500 // Information used when building the diagnostic.
Richard Smith2815e1a2012-05-25 02:17:09 +0000501 unsigned DiagKind;
Richard Smith2815e1a2012-05-25 02:17:09 +0000502 const char *Str;
Richard Smithbdb97ff2012-05-26 06:20:46 +0000503 SourceRange Range;
504
505 // FixIts to suppress the diagnosic by removing the dead condition.
506 // For all binary terminators, branch 0 is taken if the condition is true,
507 // and branch 1 is taken if the condition is false.
508 int RemoveDiagKind = -1;
509 const char *FixitStr =
510 S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
511 : (I->Output ? "1" : "0");
512 FixItHint Fixit1, Fixit2;
513
Richard Smith2815e1a2012-05-25 02:17:09 +0000514 switch (Term->getStmtClass()) {
515 default:
Richard Smithbdb97ff2012-05-26 06:20:46 +0000516 // Don't know how to report this. Just fall back to 'may be used
517 // uninitialized'. This happens for range-based for, which the user
518 // can't explicitly fix.
519 // FIXME: This also happens if the first use of a variable is always
520 // uninitialized, eg "for (int n; n < 10; ++n)". We should report that
521 // with the 'is uninitialized' diagnostic.
Richard Smith2815e1a2012-05-25 02:17:09 +0000522 continue;
523
524 // "condition is true / condition is false".
Richard Smithbdb97ff2012-05-26 06:20:46 +0000525 case Stmt::IfStmtClass: {
526 const IfStmt *IS = cast<IfStmt>(Term);
Richard Smith2815e1a2012-05-25 02:17:09 +0000527 DiagKind = 0;
528 Str = "if";
Richard Smithbdb97ff2012-05-26 06:20:46 +0000529 Range = IS->getCond()->getSourceRange();
530 RemoveDiagKind = 0;
531 CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
532 I->Output, Fixit1, Fixit2);
Richard Smith2815e1a2012-05-25 02:17:09 +0000533 break;
Richard Smithbdb97ff2012-05-26 06:20:46 +0000534 }
535 case Stmt::ConditionalOperatorClass: {
536 const ConditionalOperator *CO = cast<ConditionalOperator>(Term);
Richard Smith2815e1a2012-05-25 02:17:09 +0000537 DiagKind = 0;
538 Str = "?:";
Richard Smithbdb97ff2012-05-26 06:20:46 +0000539 Range = CO->getCond()->getSourceRange();
540 RemoveDiagKind = 0;
541 CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
542 I->Output, Fixit1, Fixit2);
Richard Smith2815e1a2012-05-25 02:17:09 +0000543 break;
Richard Smithbdb97ff2012-05-26 06:20:46 +0000544 }
Richard Smith2815e1a2012-05-25 02:17:09 +0000545 case Stmt::BinaryOperatorClass: {
546 const BinaryOperator *BO = cast<BinaryOperator>(Term);
547 if (!BO->isLogicalOp())
548 continue;
549 DiagKind = 0;
550 Str = BO->getOpcodeStr();
551 Range = BO->getLHS()->getSourceRange();
Richard Smithbdb97ff2012-05-26 06:20:46 +0000552 RemoveDiagKind = 0;
553 if ((BO->getOpcode() == BO_LAnd && I->Output) ||
554 (BO->getOpcode() == BO_LOr && !I->Output))
555 // true && y -> y, false || y -> y.
556 Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(),
557 BO->getOperatorLoc()));
558 else
559 // false && y -> false, true || y -> true.
560 Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);
Richard Smith2815e1a2012-05-25 02:17:09 +0000561 break;
562 }
563
564 // "loop is entered / loop is exited".
565 case Stmt::WhileStmtClass:
566 DiagKind = 1;
567 Str = "while";
568 Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();
Richard Smithbdb97ff2012-05-26 06:20:46 +0000569 RemoveDiagKind = 1;
570 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
Richard Smith2815e1a2012-05-25 02:17:09 +0000571 break;
572 case Stmt::ForStmtClass:
573 DiagKind = 1;
574 Str = "for";
575 Range = cast<ForStmt>(Term)->getCond()->getSourceRange();
Richard Smithbdb97ff2012-05-26 06:20:46 +0000576 RemoveDiagKind = 1;
577 if (I->Output)
578 Fixit1 = FixItHint::CreateRemoval(Range);
579 else
580 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
Richard Smith2815e1a2012-05-25 02:17:09 +0000581 break;
582
583 // "condition is true / loop is exited".
584 case Stmt::DoStmtClass:
585 DiagKind = 2;
586 Str = "do";
587 Range = cast<DoStmt>(Term)->getCond()->getSourceRange();
Richard Smithbdb97ff2012-05-26 06:20:46 +0000588 RemoveDiagKind = 1;
589 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
Richard Smith2815e1a2012-05-25 02:17:09 +0000590 break;
591
592 // "switch case is taken".
593 case Stmt::CaseStmtClass:
594 DiagKind = 3;
595 Str = "case";
596 Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange();
597 break;
598 case Stmt::DefaultStmtClass:
599 DiagKind = 3;
600 Str = "default";
601 Range = cast<DefaultStmt>(Term)->getDefaultLoc();
602 break;
603 }
604
Richard Smithbdb97ff2012-05-26 06:20:46 +0000605 S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
606 << VD->getDeclName() << IsCapturedByBlock << DiagKind
607 << Str << I->Output << Range;
608 S.Diag(User->getLocStart(), diag::note_uninit_var_use)
609 << IsCapturedByBlock << User->getSourceRange();
610 if (RemoveDiagKind != -1)
611 S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)
612 << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
613
614 Diagnosed = true;
Richard Smith2815e1a2012-05-25 02:17:09 +0000615 }
Richard Smithbdb97ff2012-05-26 06:20:46 +0000616
617 if (!Diagnosed)
618 S.Diag(Use.getUser()->getLocStart(),
619 Use.getKind() == UninitUse::Always ? diag::warn_uninit_var
620 : diag::warn_maybe_uninit_var)
621 << VD->getDeclName() << IsCapturedByBlock
622 << Use.getUser()->getSourceRange();
Richard Smith2815e1a2012-05-25 02:17:09 +0000623}
624
Chandler Carruth262d50e2011-04-05 18:27:05 +0000625/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
626/// uninitialized variable. This manages the different forms of diagnostic
627/// emitted for particular types of uses. Returns true if the use was diagnosed
Richard Smith2815e1a2012-05-25 02:17:09 +0000628/// as a warning. If a particular use is one we omit warnings for, returns
Chandler Carruth262d50e2011-04-05 18:27:05 +0000629/// false.
630static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
Richard Smith2815e1a2012-05-25 02:17:09 +0000631 const UninitUse &Use,
Ted Kremenek9e761722011-10-13 18:50:06 +0000632 bool alwaysReportSelfInit = false) {
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000633
Richard Smith2815e1a2012-05-25 02:17:09 +0000634 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) {
Richard Trieuf6278e52012-05-09 21:08:22 +0000635 // Inspect the initializer of the variable declaration which is
636 // being referenced prior to its initialization. We emit
637 // specialized diagnostics for self-initialization, and we
638 // specifically avoid warning about self references which take the
639 // form of:
640 //
641 // int x = x;
642 //
643 // This is used to indicate to GCC that 'x' is intentionally left
644 // uninitialized. Proven code paths which access 'x' in
645 // an uninitialized state after this will still warn.
646 if (const Expr *Initializer = VD->getInit()) {
647 if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())
648 return false;
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000649
Richard Trieuf6278e52012-05-09 21:08:22 +0000650 ContainsReference CR(S.Context, DRE);
651 CR.Visit(const_cast<Expr*>(Initializer));
652 if (CR.doesContainReference()) {
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000653 S.Diag(DRE->getLocStart(),
654 diag::warn_uninit_self_reference_in_init)
Richard Trieuf6278e52012-05-09 21:08:22 +0000655 << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
656 return true;
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000657 }
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000658 }
Richard Trieuf6278e52012-05-09 21:08:22 +0000659
Richard Smithbdb97ff2012-05-26 06:20:46 +0000660 DiagUninitUse(S, VD, Use, false);
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000661 } else {
Richard Smith2815e1a2012-05-25 02:17:09 +0000662 const BlockExpr *BE = cast<BlockExpr>(Use.getUser());
Richard Smithbdb97ff2012-05-26 06:20:46 +0000663 if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
664 S.Diag(BE->getLocStart(),
665 diag::warn_uninit_byref_blockvar_captured_by_block)
Fariborz Jahaniana34194f2012-03-08 00:22:50 +0000666 << VD->getDeclName();
Richard Smithbdb97ff2012-05-26 06:20:46 +0000667 else
668 DiagUninitUse(S, VD, Use, true);
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000669 }
670
671 // Report where the variable was declared when the use wasn't within
David Blaikie4f4f3492011-09-10 05:35:08 +0000672 // the initializer of that declaration & we didn't already suggest
673 // an initialization fixit.
Richard Trieuf6278e52012-05-09 21:08:22 +0000674 if (!SuggestInitializationFixit(S, VD))
Chandler Carruth4c4983b2011-04-05 18:18:05 +0000675 S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
676 << VD->getDeclName();
677
Chandler Carruth262d50e2011-04-05 18:27:05 +0000678 return true;
Chandler Carruth64fb9592011-04-05 18:18:08 +0000679}
680
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000681namespace {
682 class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
683 public:
684 FallthroughMapper(Sema &S)
685 : FoundSwitchStatements(false),
686 S(S) {
687 }
688
689 bool foundSwitchStatements() const { return FoundSwitchStatements; }
690
691 void markFallthroughVisited(const AttributedStmt *Stmt) {
692 bool Found = FallthroughStmts.erase(Stmt);
693 assert(Found);
Kaelyn Uhrain3bb29942012-05-03 19:46:38 +0000694 (void)Found;
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000695 }
696
697 typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
698
699 const AttrStmts &getFallthroughStmts() const {
700 return FallthroughStmts;
701 }
702
703 bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
704 int UnannotatedCnt = 0;
705 AnnotatedCnt = 0;
706
707 std::deque<const CFGBlock*> BlockQueue;
708
709 std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue));
710
711 while (!BlockQueue.empty()) {
712 const CFGBlock *P = BlockQueue.front();
713 BlockQueue.pop_front();
714
715 const Stmt *Term = P->getTerminator();
716 if (Term && isa<SwitchStmt>(Term))
717 continue; // Switch statement, good.
718
719 const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
720 if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
721 continue; // Previous case label has no statements, good.
722
723 if (P->pred_begin() == P->pred_end()) { // The block is unreachable.
724 // This only catches trivially unreachable blocks.
725 for (CFGBlock::const_iterator ElIt = P->begin(), ElEnd = P->end();
726 ElIt != ElEnd; ++ElIt) {
727 if (const CFGStmt *CS = ElIt->getAs<CFGStmt>()){
728 if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
729 S.Diag(AS->getLocStart(),
730 diag::warn_fallthrough_attr_unreachable);
731 markFallthroughVisited(AS);
732 ++AnnotatedCnt;
733 }
734 // Don't care about other unreachable statements.
735 }
736 }
737 // If there are no unreachable statements, this may be a special
738 // case in CFG:
739 // case X: {
740 // A a; // A has a destructor.
741 // break;
742 // }
743 // // <<<< This place is represented by a 'hanging' CFG block.
744 // case Y:
745 continue;
746 }
747
748 const Stmt *LastStmt = getLastStmt(*P);
749 if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
750 markFallthroughVisited(AS);
751 ++AnnotatedCnt;
752 continue; // Fallthrough annotation, good.
753 }
754
755 if (!LastStmt) { // This block contains no executable statements.
756 // Traverse its predecessors.
757 std::copy(P->pred_begin(), P->pred_end(),
758 std::back_inserter(BlockQueue));
759 continue;
760 }
761
762 ++UnannotatedCnt;
763 }
764 return !!UnannotatedCnt;
765 }
766
767 // RecursiveASTVisitor setup.
768 bool shouldWalkTypesOfTypeLocs() const { return false; }
769
770 bool VisitAttributedStmt(AttributedStmt *S) {
771 if (asFallThroughAttr(S))
772 FallthroughStmts.insert(S);
773 return true;
774 }
775
776 bool VisitSwitchStmt(SwitchStmt *S) {
777 FoundSwitchStatements = true;
778 return true;
779 }
780
781 private:
782
783 static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
784 if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
785 if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
786 return AS;
787 }
788 return 0;
789 }
790
791 static const Stmt *getLastStmt(const CFGBlock &B) {
792 if (const Stmt *Term = B.getTerminator())
793 return Term;
794 for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
795 ElemEnd = B.rend();
796 ElemIt != ElemEnd; ++ElemIt) {
797 if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>())
798 return CS->getStmt();
799 }
800 // Workaround to detect a statement thrown out by CFGBuilder:
801 // case X: {} case Y:
802 // case X: ; case Y:
803 if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
804 if (!isa<SwitchCase>(SW->getSubStmt()))
805 return SW->getSubStmt();
806
807 return 0;
808 }
809
810 bool FoundSwitchStatements;
811 AttrStmts FallthroughStmts;
812 Sema &S;
813 };
814}
815
Alexander Kornienko19736342012-06-02 01:01:07 +0000816static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
Sean Huntc2f51cf2012-06-15 21:22:05 +0000817 bool PerFunction) {
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000818 FallthroughMapper FM(S);
819 FM.TraverseStmt(AC.getBody());
820
821 if (!FM.foundSwitchStatements())
822 return;
823
Sean Huntc2f51cf2012-06-15 21:22:05 +0000824 if (PerFunction && FM.getFallthroughStmts().empty())
Alexander Kornienko19736342012-06-02 01:01:07 +0000825 return;
826
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000827 CFG *Cfg = AC.getCFG();
828
829 if (!Cfg)
830 return;
831
832 int AnnotatedCnt;
833
834 for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
835 const CFGBlock &B = **I;
836 const Stmt *Label = B.getLabel();
837
838 if (!Label || !isa<SwitchCase>(Label))
839 continue;
840
841 if (!FM.checkFallThroughIntoBlock(B, AnnotatedCnt))
842 continue;
843
Alexander Kornienko19736342012-06-02 01:01:07 +0000844 S.Diag(Label->getLocStart(),
Sean Huntc2f51cf2012-06-15 21:22:05 +0000845 PerFunction ? diag::warn_unannotated_fallthrough_per_function
846 : diag::warn_unannotated_fallthrough);
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000847
848 if (!AnnotatedCnt) {
849 SourceLocation L = Label->getLocStart();
850 if (L.isMacroID())
851 continue;
852 if (S.getLangOpts().CPlusPlus0x) {
Alexander Kornienkoa189d892012-05-26 00:49:15 +0000853 const Stmt *Term = B.getTerminator();
854 if (!(B.empty() && Term && isa<BreakStmt>(Term))) {
855 S.Diag(L, diag::note_insert_fallthrough_fixit) <<
856 FixItHint::CreateInsertion(L, "[[clang::fallthrough]]; ");
857 }
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000858 }
859 S.Diag(L, diag::note_insert_break_fixit) <<
860 FixItHint::CreateInsertion(L, "break; ");
861 }
862 }
863
864 const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts();
865 for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(),
866 E = Fallthroughs.end();
867 I != E; ++I) {
868 S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
869 }
870
871}
872
Ted Kremenek610068c2011-01-15 02:58:47 +0000873namespace {
Jordan Rose58b6bdc2012-09-28 22:21:30 +0000874 typedef std::pair<const Stmt *,
875 sema::FunctionScopeInfo::WeakObjectUseMap::const_iterator>
876 StmtUsesPair;
877}
878
879template<>
880class BeforeThanCompare<StmtUsesPair> {
881 const SourceManager &SM;
882
883public:
884 explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
885
886 bool operator()(const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
887 return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
888 RHS.first->getLocStart());
889 }
890};
891
892
893static void diagnoseRepeatedUseOfWeak(Sema &S,
894 const sema::FunctionScopeInfo *CurFn,
895 const Decl *D) {
896 typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
897 typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
898 typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
899
900 const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses();
901
902 // Extract all weak objects that are referenced more than once.
903 SmallVector<StmtUsesPair, 8> UsesByStmt;
904 for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();
905 I != E; ++I) {
906 const WeakUseVector &Uses = I->second;
907 if (Uses.size() <= 1)
908 continue;
909
910 // Find the first read of the weak object.
911 WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
912 for ( ; UI != UE; ++UI) {
913 if (UI->isUnsafe())
914 break;
915 }
916
917 // If there were only writes to this object, don't warn.
918 if (UI == UE)
919 continue;
920
921 UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));
922 }
923
924 if (UsesByStmt.empty())
925 return;
926
927 // Sort by first use so that we emit the warnings in a deterministic order.
928 std::sort(UsesByStmt.begin(), UsesByStmt.end(),
929 BeforeThanCompare<StmtUsesPair>(S.getSourceManager()));
930
931 // Classify the current code body for better warning text.
932 // This enum should stay in sync with the cases in
933 // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
934 // FIXME: Should we use a common classification enum and the same set of
935 // possibilities all throughout Sema?
936 enum {
937 Function,
938 Method,
939 Block,
940 Lambda
941 } FunctionKind;
942
943 if (isa<sema::BlockScopeInfo>(CurFn))
944 FunctionKind = Block;
945 else if (isa<sema::LambdaScopeInfo>(CurFn))
946 FunctionKind = Lambda;
947 else if (isa<ObjCMethodDecl>(D))
948 FunctionKind = Method;
949 else
950 FunctionKind = Function;
951
952 // Iterate through the sorted problems and emit warnings for each.
953 for (SmallVectorImpl<StmtUsesPair>::const_iterator I = UsesByStmt.begin(),
954 E = UsesByStmt.end();
955 I != E; ++I) {
956 const Stmt *FirstRead = I->first;
957 const WeakObjectProfileTy &Key = I->second->first;
958 const WeakUseVector &Uses = I->second->second;
959
Jordan Rose7a270482012-09-28 22:21:35 +0000960 // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy
961 // may not contain enough information to determine that these are different
962 // properties. We can only be 100% sure of a repeated use in certain cases,
963 // and we adjust the diagnostic kind accordingly so that the less certain
964 // case can be turned off if it is too noisy.
Jordan Rose58b6bdc2012-09-28 22:21:30 +0000965 unsigned DiagKind;
966 if (Key.isExactProfile())
967 DiagKind = diag::warn_arc_repeated_use_of_weak;
968 else
969 DiagKind = diag::warn_arc_possible_repeated_use_of_weak;
970
Jordan Rose7a270482012-09-28 22:21:35 +0000971 // Classify the weak object being accessed for better warning text.
972 // This enum should stay in sync with the cases in
973 // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
974 enum {
975 Variable,
976 Property,
977 ImplicitProperty,
978 Ivar
979 } ObjectKind;
980
981 const NamedDecl *D = Key.getProperty();
982 if (isa<VarDecl>(D))
983 ObjectKind = Variable;
984 else if (isa<ObjCPropertyDecl>(D))
985 ObjectKind = Property;
986 else if (isa<ObjCMethodDecl>(D))
987 ObjectKind = ImplicitProperty;
988 else if (isa<ObjCIvarDecl>(D))
989 ObjectKind = Ivar;
990 else
991 llvm_unreachable("Unexpected weak object kind!");
992
Jordan Rose58b6bdc2012-09-28 22:21:30 +0000993 // Show the first time the object was read.
994 S.Diag(FirstRead->getLocStart(), DiagKind)
Jordan Rose7a270482012-09-28 22:21:35 +0000995 << ObjectKind << D << FunctionKind
Jordan Rose58b6bdc2012-09-28 22:21:30 +0000996 << FirstRead->getSourceRange();
997
998 // Print all the other accesses as notes.
999 for (WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
1000 UI != UE; ++UI) {
1001 if (UI->getUseExpr() == FirstRead)
1002 continue;
1003 S.Diag(UI->getUseExpr()->getLocStart(),
1004 diag::note_arc_weak_also_accessed_here)
1005 << UI->getUseExpr()->getSourceRange();
1006 }
1007 }
1008}
1009
1010
1011namespace {
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001012struct SLocSort {
Ted Kremenekf7bafc72011-03-15 04:57:38 +00001013 bool operator()(const UninitUse &a, const UninitUse &b) {
Richard Smith2815e1a2012-05-25 02:17:09 +00001014 // Prefer a more confident report over a less confident one.
1015 if (a.getKind() != b.getKind())
1016 return a.getKind() > b.getKind();
1017 SourceLocation aLoc = a.getUser()->getLocStart();
1018 SourceLocation bLoc = b.getUser()->getLocStart();
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001019 return aLoc.getRawEncoding() < bLoc.getRawEncoding();
1020 }
1021};
1022
Ted Kremenek610068c2011-01-15 02:58:47 +00001023class UninitValsDiagReporter : public UninitVariablesHandler {
1024 Sema &S;
Chris Lattner5f9e2722011-07-23 10:55:15 +00001025 typedef SmallVector<UninitUse, 2> UsesVec;
Ted Kremenek9e761722011-10-13 18:50:06 +00001026 typedef llvm::DenseMap<const VarDecl *, std::pair<UsesVec*, bool> > UsesMap;
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001027 UsesMap *uses;
1028
Ted Kremenek610068c2011-01-15 02:58:47 +00001029public:
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001030 UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
1031 ~UninitValsDiagReporter() {
1032 flushDiagnostics();
1033 }
Ted Kremenek9e761722011-10-13 18:50:06 +00001034
1035 std::pair<UsesVec*, bool> &getUses(const VarDecl *vd) {
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001036 if (!uses)
1037 uses = new UsesMap();
Ted Kremenek9e761722011-10-13 18:50:06 +00001038
1039 UsesMap::mapped_type &V = (*uses)[vd];
1040 UsesVec *&vec = V.first;
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001041 if (!vec)
1042 vec = new UsesVec();
1043
Ted Kremenek9e761722011-10-13 18:50:06 +00001044 return V;
1045 }
1046
Richard Smith2815e1a2012-05-25 02:17:09 +00001047 void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) {
1048 getUses(vd).first->push_back(use);
Ted Kremenek9e761722011-10-13 18:50:06 +00001049 }
1050
1051 void handleSelfInit(const VarDecl *vd) {
1052 getUses(vd).second = true;
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001053 }
1054
1055 void flushDiagnostics() {
1056 if (!uses)
1057 return;
Ted Kremenek609e3172011-02-02 23:35:53 +00001058
Richard Smith81891882012-05-24 23:45:35 +00001059 // FIXME: This iteration order, and thus the resulting diagnostic order,
1060 // is nondeterministic.
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001061 for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
1062 const VarDecl *vd = i->first;
Ted Kremenek9e761722011-10-13 18:50:06 +00001063 const UsesMap::mapped_type &V = i->second;
Ted Kremenek609e3172011-02-02 23:35:53 +00001064
Ted Kremenek9e761722011-10-13 18:50:06 +00001065 UsesVec *vec = V.first;
1066 bool hasSelfInit = V.second;
1067
1068 // Specially handle the case where we have uses of an uninitialized
1069 // variable, but the root cause is an idiomatic self-init. We want
1070 // to report the diagnostic at the self-init since that is the root cause.
Matt Beaumont-Gay0d381812011-10-19 18:53:03 +00001071 if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
Richard Smith2815e1a2012-05-25 02:17:09 +00001072 DiagnoseUninitializedUse(S, vd,
1073 UninitUse(vd->getInit()->IgnoreParenCasts(),
1074 /* isAlwaysUninit */ true),
Matt Beaumont-Gay0d381812011-10-19 18:53:03 +00001075 /* alwaysReportSelfInit */ true);
Ted Kremenek9e761722011-10-13 18:50:06 +00001076 else {
1077 // Sort the uses by their SourceLocations. While not strictly
1078 // guaranteed to produce them in line/column order, this will provide
1079 // a stable ordering.
1080 std::sort(vec->begin(), vec->end(), SLocSort());
1081
1082 for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
1083 ++vi) {
Richard Smith2815e1a2012-05-25 02:17:09 +00001084 // If we have self-init, downgrade all uses to 'may be uninitialized'.
1085 UninitUse Use = hasSelfInit ? UninitUse(vi->getUser(), false) : *vi;
1086
1087 if (DiagnoseUninitializedUse(S, vd, Use))
Ted Kremenek9e761722011-10-13 18:50:06 +00001088 // Skip further diagnostics for this variable. We try to warn only
1089 // on the first point at which a variable is used uninitialized.
1090 break;
1091 }
Chandler Carruth64fb9592011-04-05 18:18:08 +00001092 }
Ted Kremenek9e761722011-10-13 18:50:06 +00001093
1094 // Release the uses vector.
Ted Kremenek94b1b4d2011-01-21 19:41:41 +00001095 delete vec;
1096 }
1097 delete uses;
Ted Kremenek610068c2011-01-15 02:58:47 +00001098 }
Matt Beaumont-Gay0d381812011-10-19 18:53:03 +00001099
1100private:
1101 static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
1102 for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
Richard Smith2815e1a2012-05-25 02:17:09 +00001103 if (i->getKind() == UninitUse::Always) {
Matt Beaumont-Gay0d381812011-10-19 18:53:03 +00001104 return true;
1105 }
1106 }
1107 return false;
1108}
Ted Kremenek610068c2011-01-15 02:58:47 +00001109};
1110}
1111
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001112
1113//===----------------------------------------------------------------------===//
1114// -Wthread-safety
1115//===----------------------------------------------------------------------===//
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001116namespace clang {
1117namespace thread_safety {
Richard Smith2e515622012-02-03 04:45:26 +00001118typedef llvm::SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
1119typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
Benjamin Kramerecafd302012-03-26 14:05:40 +00001120typedef std::list<DelayedDiag> DiagList;
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001121
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001122struct SortDiagBySourceLocation {
Benjamin Kramerecafd302012-03-26 14:05:40 +00001123 SourceManager &SM;
1124 SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001125
1126 bool operator()(const DelayedDiag &left, const DelayedDiag &right) {
1127 // Although this call will be slow, this is only called when outputting
1128 // multiple warnings.
Benjamin Kramerecafd302012-03-26 14:05:40 +00001129 return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001130 }
1131};
1132
David Blaikie99ba9e32011-12-20 02:48:34 +00001133namespace {
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001134class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {
1135 Sema &S;
1136 DiagList Warnings;
Richard Smith2e515622012-02-03 04:45:26 +00001137 SourceLocation FunLocation, FunEndLocation;
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001138
1139 // Helper functions
1140 void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001141 // Gracefully handle rare cases when the analysis can't get a more
1142 // precise source location.
1143 if (!Loc.isValid())
1144 Loc = FunLocation;
Richard Smith2e515622012-02-03 04:45:26 +00001145 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << LockName);
1146 Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001147 }
1148
1149 public:
Richard Smith2e515622012-02-03 04:45:26 +00001150 ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
1151 : S(S), FunLocation(FL), FunEndLocation(FEL) {}
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001152
1153 /// \brief Emit all buffered diagnostics in order of sourcelocation.
1154 /// We need to output diagnostics produced while iterating through
1155 /// the lockset in deterministic order, so this function orders diagnostics
1156 /// and outputs them.
1157 void emitDiagnostics() {
Benjamin Kramerecafd302012-03-26 14:05:40 +00001158 Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001159 for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
Richard Smith2e515622012-02-03 04:45:26 +00001160 I != E; ++I) {
1161 S.Diag(I->first.first, I->first.second);
1162 const OptionalNotes &Notes = I->second;
1163 for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI)
1164 S.Diag(Notes[NoteI].first, Notes[NoteI].second);
1165 }
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001166 }
1167
Caitlin Sadowski99107eb2011-09-09 16:21:55 +00001168 void handleInvalidLockExp(SourceLocation Loc) {
Richard Smith2e515622012-02-03 04:45:26 +00001169 PartialDiagnosticAt Warning(Loc,
1170 S.PDiag(diag::warn_cannot_resolve_lock) << Loc);
1171 Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
Caitlin Sadowski99107eb2011-09-09 16:21:55 +00001172 }
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001173 void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {
1174 warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc);
1175 }
1176
1177 void handleDoubleLock(Name LockName, SourceLocation Loc) {
1178 warnLockMismatch(diag::warn_double_lock, LockName, Loc);
1179 }
1180
Richard Smith2e515622012-02-03 04:45:26 +00001181 void handleMutexHeldEndOfScope(Name LockName, SourceLocation LocLocked,
1182 SourceLocation LocEndOfScope,
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001183 LockErrorKind LEK){
1184 unsigned DiagID = 0;
1185 switch (LEK) {
1186 case LEK_LockedSomePredecessors:
Richard Smith2e515622012-02-03 04:45:26 +00001187 DiagID = diag::warn_lock_some_predecessors;
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001188 break;
1189 case LEK_LockedSomeLoopIterations:
1190 DiagID = diag::warn_expecting_lock_held_on_loop;
1191 break;
1192 case LEK_LockedAtEndOfFunction:
1193 DiagID = diag::warn_no_unlock;
1194 break;
DeLesley Hutchins879a4332012-07-02 22:16:54 +00001195 case LEK_NotLockedAtEndOfFunction:
1196 DiagID = diag::warn_expecting_locked;
1197 break;
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001198 }
Richard Smith2e515622012-02-03 04:45:26 +00001199 if (LocEndOfScope.isInvalid())
1200 LocEndOfScope = FunEndLocation;
1201
1202 PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName);
1203 PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here));
1204 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001205 }
1206
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001207
1208 void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
1209 SourceLocation Loc2) {
Richard Smith2e515622012-02-03 04:45:26 +00001210 PartialDiagnosticAt Warning(
1211 Loc1, S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName);
1212 PartialDiagnosticAt Note(
1213 Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << LockName);
1214 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001215 }
1216
1217 void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
1218 AccessKind AK, SourceLocation Loc) {
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +00001219 assert((POK == POK_VarAccess || POK == POK_VarDereference)
1220 && "Only works for variables");
1221 unsigned DiagID = POK == POK_VarAccess?
1222 diag::warn_variable_requires_any_lock:
1223 diag::warn_var_deref_requires_any_lock;
Richard Smith2e515622012-02-03 04:45:26 +00001224 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
DeLesley Hutchins5b280f22012-09-19 19:18:29 +00001225 << D->getNameAsString() << getLockKindFromAccessKind(AK));
Richard Smith2e515622012-02-03 04:45:26 +00001226 Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001227 }
1228
1229 void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK,
DeLesley Hutchins3f0ec522012-09-10 19:58:23 +00001230 Name LockName, LockKind LK, SourceLocation Loc,
1231 Name *PossibleMatch) {
Caitlin Sadowskie87158d2011-09-13 18:01:58 +00001232 unsigned DiagID = 0;
DeLesley Hutchins3f0ec522012-09-10 19:58:23 +00001233 if (PossibleMatch) {
1234 switch (POK) {
1235 case POK_VarAccess:
1236 DiagID = diag::warn_variable_requires_lock_precise;
1237 break;
1238 case POK_VarDereference:
1239 DiagID = diag::warn_var_deref_requires_lock_precise;
1240 break;
1241 case POK_FunctionCall:
1242 DiagID = diag::warn_fun_requires_lock_precise;
1243 break;
1244 }
1245 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
DeLesley Hutchins5b280f22012-09-19 19:18:29 +00001246 << D->getNameAsString() << LockName << LK);
DeLesley Hutchins3f0ec522012-09-10 19:58:23 +00001247 PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
1248 << *PossibleMatch);
1249 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
1250 } else {
1251 switch (POK) {
1252 case POK_VarAccess:
1253 DiagID = diag::warn_variable_requires_lock;
1254 break;
1255 case POK_VarDereference:
1256 DiagID = diag::warn_var_deref_requires_lock;
1257 break;
1258 case POK_FunctionCall:
1259 DiagID = diag::warn_fun_requires_lock;
1260 break;
1261 }
1262 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
DeLesley Hutchins5b280f22012-09-19 19:18:29 +00001263 << D->getNameAsString() << LockName << LK);
DeLesley Hutchins3f0ec522012-09-10 19:58:23 +00001264 Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001265 }
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001266 }
1267
1268 void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) {
Richard Smith2e515622012-02-03 04:45:26 +00001269 PartialDiagnosticAt Warning(Loc,
1270 S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName);
1271 Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001272 }
1273};
1274}
1275}
David Blaikie99ba9e32011-12-20 02:48:34 +00001276}
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001277
Ted Kremenek610068c2011-01-15 02:58:47 +00001278//===----------------------------------------------------------------------===//
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001279// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
1280// warnings on a function, method, or block.
1281//===----------------------------------------------------------------------===//
1282
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001283clang::sema::AnalysisBasedWarnings::Policy::Policy() {
1284 enableCheckFallThrough = 1;
1285 enableCheckUnreachable = 0;
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001286 enableThreadSafetyAnalysis = 0;
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001287}
1288
Chandler Carruth5d989942011-07-06 16:21:37 +00001289clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
1290 : S(s),
1291 NumFunctionsAnalyzed(0),
Benjamin Kramer54cf3412011-07-08 20:38:53 +00001292 NumFunctionsWithBadCFGs(0),
Chandler Carruth5d989942011-07-06 16:21:37 +00001293 NumCFGBlocks(0),
Benjamin Kramer54cf3412011-07-08 20:38:53 +00001294 MaxCFGBlocksPerFunction(0),
1295 NumUninitAnalysisFunctions(0),
1296 NumUninitAnalysisVariables(0),
1297 MaxUninitAnalysisVariablesPerFunction(0),
1298 NumUninitAnalysisBlockVisits(0),
1299 MaxUninitAnalysisBlockVisitsPerFunction(0) {
David Blaikied6471f72011-09-25 23:23:43 +00001300 DiagnosticsEngine &D = S.getDiagnostics();
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001301 DefaultPolicy.enableCheckUnreachable = (unsigned)
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +00001302 (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
David Blaikied6471f72011-09-25 23:23:43 +00001303 DiagnosticsEngine::Ignored);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001304 DefaultPolicy.enableThreadSafetyAnalysis = (unsigned)
1305 (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) !=
David Blaikied6471f72011-09-25 23:23:43 +00001306 DiagnosticsEngine::Ignored);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001307
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001308}
1309
Ted Kremenek351ba912011-02-23 01:52:04 +00001310static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00001311 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
Ted Kremenek351ba912011-02-23 01:52:04 +00001312 i = fscope->PossiblyUnreachableDiags.begin(),
1313 e = fscope->PossiblyUnreachableDiags.end();
1314 i != e; ++i) {
1315 const sema::PossiblyUnreachableDiag &D = *i;
1316 S.Diag(D.Loc, D.PD);
1317 }
1318}
1319
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001320void clang::sema::
1321AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
Ted Kremenek283a3582011-02-23 01:51:53 +00001322 sema::FunctionScopeInfo *fscope,
Ted Kremenek3ed6fc02011-02-23 01:51:48 +00001323 const Decl *D, const BlockExpr *blkExpr) {
Ted Kremenekd068aab2010-03-20 21:11:09 +00001324
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001325 // We avoid doing analysis-based warnings when there are errors for
1326 // two reasons:
1327 // (1) The CFGs often can't be constructed (if the body is invalid), so
1328 // don't bother trying.
1329 // (2) The code already has problems; running the analysis just takes more
1330 // time.
David Blaikied6471f72011-09-25 23:23:43 +00001331 DiagnosticsEngine &Diags = S.getDiagnostics();
Ted Kremenek99e81922010-04-30 21:49:25 +00001332
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001333 // Do not do any analysis for declarations in system headers if we are
1334 // going to just ignore them.
Ted Kremenek99e81922010-04-30 21:49:25 +00001335 if (Diags.getSuppressSystemWarnings() &&
Ted Kremenekd064fdc2010-03-23 00:13:23 +00001336 S.SourceMgr.isInSystemHeader(D->getLocation()))
1337 return;
1338
John McCalle0054f62010-08-25 05:56:39 +00001339 // For code in dependent contexts, we'll do this at instantiation time.
David Blaikie23661d32012-01-24 04:51:48 +00001340 if (cast<DeclContext>(D)->isDependentContext())
1341 return;
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001342
Ted Kremenek351ba912011-02-23 01:52:04 +00001343 if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
1344 // Flush out any possibly unreachable diagnostics.
1345 flushDiagnostics(S, fscope);
1346 return;
1347 }
1348
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001349 const Stmt *Body = D->getBody();
1350 assert(Body);
1351
Jordy Rosed2001872012-04-28 01:58:08 +00001352 AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D);
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +00001353
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001354 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
1355 // explosion for destrutors that can result and the compile time hit.
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +00001356 AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
1357 AC.getCFGBuildOptions().AddEHEdges = false;
1358 AC.getCFGBuildOptions().AddInitializers = true;
1359 AC.getCFGBuildOptions().AddImplicitDtors = true;
Jordan Rosefaadf482012-09-05 23:11:06 +00001360 AC.getCFGBuildOptions().AddTemporaryDtors = true;
1361
Ted Kremenek0c8e5a02011-07-19 14:18:48 +00001362 // Force that certain expressions appear as CFGElements in the CFG. This
1363 // is used to speed up various analyses.
1364 // FIXME: This isn't the right factoring. This is here for initial
1365 // prototyping, but we need a way for analyses to say what expressions they
1366 // expect to always be CFGElements and then fill in the BuildOptions
1367 // appropriately. This is essentially a layering violation.
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001368 if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis) {
1369 // Unreachable code analysis and thread safety require a linearized CFG.
Ted Kremenek0f3b4ca2011-08-23 23:05:11 +00001370 AC.getCFGBuildOptions().setAllAlwaysAdd();
1371 }
1372 else {
1373 AC.getCFGBuildOptions()
1374 .setAlwaysAdd(Stmt::BinaryOperatorClass)
Richard Smith6cfa78f2012-07-17 01:27:33 +00001375 .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
Ted Kremenek0f3b4ca2011-08-23 23:05:11 +00001376 .setAlwaysAdd(Stmt::BlockExprClass)
1377 .setAlwaysAdd(Stmt::CStyleCastExprClass)
1378 .setAlwaysAdd(Stmt::DeclRefExprClass)
1379 .setAlwaysAdd(Stmt::ImplicitCastExprClass)
Richard Smithe0d3b4c2012-05-03 18:27:39 +00001380 .setAlwaysAdd(Stmt::UnaryOperatorClass)
1381 .setAlwaysAdd(Stmt::AttributedStmtClass);
Ted Kremenek0f3b4ca2011-08-23 23:05:11 +00001382 }
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001383
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +00001384 // Construct the analysis context with the specified CFG build options.
1385
Ted Kremenek351ba912011-02-23 01:52:04 +00001386 // Emit delayed diagnostics.
David Blaikie23661d32012-01-24 04:51:48 +00001387 if (!fscope->PossiblyUnreachableDiags.empty()) {
Ted Kremenek351ba912011-02-23 01:52:04 +00001388 bool analyzed = false;
Ted Kremenek0d28d362011-03-10 03:50:34 +00001389
1390 // Register the expressions with the CFGBuilder.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001391 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
Ted Kremenek0d28d362011-03-10 03:50:34 +00001392 i = fscope->PossiblyUnreachableDiags.begin(),
1393 e = fscope->PossiblyUnreachableDiags.end();
1394 i != e; ++i) {
1395 if (const Stmt *stmt = i->stmt)
1396 AC.registerForcedBlockExpression(stmt);
1397 }
1398
1399 if (AC.getCFG()) {
1400 analyzed = true;
Chris Lattner5f9e2722011-07-23 10:55:15 +00001401 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
Ted Kremenek0d28d362011-03-10 03:50:34 +00001402 i = fscope->PossiblyUnreachableDiags.begin(),
1403 e = fscope->PossiblyUnreachableDiags.end();
1404 i != e; ++i)
1405 {
1406 const sema::PossiblyUnreachableDiag &D = *i;
1407 bool processed = false;
1408 if (const Stmt *stmt = i->stmt) {
1409 const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
Eli Friedman71b8fb52012-01-21 01:01:51 +00001410 CFGReverseBlockReachabilityAnalysis *cra =
1411 AC.getCFGReachablityAnalysis();
1412 // FIXME: We should be able to assert that block is non-null, but
1413 // the CFG analysis can skip potentially-evaluated expressions in
1414 // edge cases; see test/Sema/vla-2.c.
1415 if (block && cra) {
Ted Kremenek351ba912011-02-23 01:52:04 +00001416 // Can this block be reached from the entrance?
Ted Kremenek0d28d362011-03-10 03:50:34 +00001417 if (cra->isReachable(&AC.getCFG()->getEntry(), block))
Ted Kremenek351ba912011-02-23 01:52:04 +00001418 S.Diag(D.Loc, D.PD);
Ted Kremenek0d28d362011-03-10 03:50:34 +00001419 processed = true;
Ted Kremenek351ba912011-02-23 01:52:04 +00001420 }
1421 }
Ted Kremenek0d28d362011-03-10 03:50:34 +00001422 if (!processed) {
1423 // Emit the warning anyway if we cannot map to a basic block.
1424 S.Diag(D.Loc, D.PD);
1425 }
Ted Kremenek351ba912011-02-23 01:52:04 +00001426 }
Ted Kremenek0d28d362011-03-10 03:50:34 +00001427 }
Ted Kremenek351ba912011-02-23 01:52:04 +00001428
1429 if (!analyzed)
1430 flushDiagnostics(S, fscope);
1431 }
1432
1433
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001434 // Warning: check missing 'return'
David Blaikie23661d32012-01-24 04:51:48 +00001435 if (P.enableCheckFallThrough) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001436 const CheckFallThroughDiagnostics &CD =
1437 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
Douglas Gregor793cd1c2012-02-15 16:20:15 +00001438 : (isa<CXXMethodDecl>(D) &&
1439 cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
1440 cast<CXXMethodDecl>(D)->getParent()->isLambda())
1441 ? CheckFallThroughDiagnostics::MakeForLambda()
1442 : CheckFallThroughDiagnostics::MakeForFunction(D));
Ted Kremenek3ed6fc02011-02-23 01:51:48 +00001443 CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001444 }
1445
1446 // Warning: check for unreachable code
Ted Kremenek5dfee062011-11-30 21:22:09 +00001447 if (P.enableCheckUnreachable) {
1448 // Only check for unreachable code on non-template instantiations.
1449 // Different template instantiations can effectively change the control-flow
1450 // and it is very difficult to prove that a snippet of code in a template
1451 // is unreachable for all instantiations.
Ted Kremenek75df4ee2011-12-01 00:59:17 +00001452 bool isTemplateInstantiation = false;
1453 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
1454 isTemplateInstantiation = Function->isTemplateInstantiation();
1455 if (!isTemplateInstantiation)
Ted Kremenek5dfee062011-11-30 21:22:09 +00001456 CheckUnreachable(S, AC);
1457 }
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001458
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001459 // Check for thread safety violations
David Blaikie23661d32012-01-24 04:51:48 +00001460 if (P.enableThreadSafetyAnalysis) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001461 SourceLocation FL = AC.getDecl()->getLocation();
Richard Smith2e515622012-02-03 04:45:26 +00001462 SourceLocation FEL = AC.getDecl()->getLocEnd();
1463 thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
Caitlin Sadowski75f23ae2011-09-09 16:04:02 +00001464 thread_safety::runThreadSafetyAnalysis(AC, Reporter);
1465 Reporter.emitDiagnostics();
1466 }
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001467
Ted Kremeneka8c17a52011-01-25 19:13:48 +00001468 if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
David Blaikied6471f72011-09-25 23:23:43 +00001469 != DiagnosticsEngine::Ignored ||
Richard Smith2815e1a2012-05-25 02:17:09 +00001470 Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart())
1471 != DiagnosticsEngine::Ignored ||
Ted Kremenek76709bf2011-03-15 05:22:28 +00001472 Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
David Blaikied6471f72011-09-25 23:23:43 +00001473 != DiagnosticsEngine::Ignored) {
Ted Kremenekc5e43c12011-03-17 05:29:57 +00001474 if (CFG *cfg = AC.getCFG()) {
Ted Kremenekc21fed32011-01-18 21:18:58 +00001475 UninitValsDiagReporter reporter(S);
Fariborz Jahanian57080fb2011-07-16 18:31:33 +00001476 UninitVariablesAnalysisStats stats;
Benjamin Kramer12efd572011-07-16 20:13:06 +00001477 std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));
Ted Kremeneka8c17a52011-01-25 19:13:48 +00001478 runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
Chandler Carruth5d989942011-07-06 16:21:37 +00001479 reporter, stats);
1480
1481 if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
1482 ++NumUninitAnalysisFunctions;
1483 NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
1484 NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
1485 MaxUninitAnalysisVariablesPerFunction =
1486 std::max(MaxUninitAnalysisVariablesPerFunction,
1487 stats.NumVariablesAnalyzed);
1488 MaxUninitAnalysisBlockVisitsPerFunction =
1489 std::max(MaxUninitAnalysisBlockVisitsPerFunction,
1490 stats.NumBlockVisits);
1491 }
Ted Kremenek610068c2011-01-15 02:58:47 +00001492 }
1493 }
Chandler Carruth5d989942011-07-06 16:21:37 +00001494
Alexander Kornienko19736342012-06-02 01:01:07 +00001495 bool FallThroughDiagFull =
1496 Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
1497 D->getLocStart()) != DiagnosticsEngine::Ignored;
Sean Huntc2f51cf2012-06-15 21:22:05 +00001498 bool FallThroughDiagPerFunction =
1499 Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function,
Alexander Kornienko19736342012-06-02 01:01:07 +00001500 D->getLocStart()) != DiagnosticsEngine::Ignored;
Sean Huntc2f51cf2012-06-15 21:22:05 +00001501 if (FallThroughDiagFull || FallThroughDiagPerFunction) {
Alexander Kornienko19736342012-06-02 01:01:07 +00001502 DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
Richard Smithe0d3b4c2012-05-03 18:27:39 +00001503 }
1504
Jordan Rose58b6bdc2012-09-28 22:21:30 +00001505 if (S.getLangOpts().ObjCARCWeak &&
1506 Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
1507 D->getLocStart()) != DiagnosticsEngine::Ignored)
1508 diagnoseRepeatedUseOfWeak(S, fscope, D);
1509
Chandler Carruth5d989942011-07-06 16:21:37 +00001510 // Collect statistics about the CFG if it was built.
1511 if (S.CollectStats && AC.isCFGBuilt()) {
1512 ++NumFunctionsAnalyzed;
1513 if (CFG *cfg = AC.getCFG()) {
1514 // If we successfully built a CFG for this context, record some more
1515 // detail information about it.
Chandler Carruth3ea4c492011-07-06 22:21:45 +00001516 NumCFGBlocks += cfg->getNumBlockIDs();
Chandler Carruth5d989942011-07-06 16:21:37 +00001517 MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
Chandler Carruth3ea4c492011-07-06 22:21:45 +00001518 cfg->getNumBlockIDs());
Chandler Carruth5d989942011-07-06 16:21:37 +00001519 } else {
1520 ++NumFunctionsWithBadCFGs;
1521 }
1522 }
1523}
1524
1525void clang::sema::AnalysisBasedWarnings::PrintStats() const {
1526 llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
1527
1528 unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
1529 unsigned AvgCFGBlocksPerFunction =
1530 !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
1531 llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
1532 << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
1533 << " " << NumCFGBlocks << " CFG blocks built.\n"
1534 << " " << AvgCFGBlocksPerFunction
1535 << " average CFG blocks per function.\n"
1536 << " " << MaxCFGBlocksPerFunction
1537 << " max CFG blocks per function.\n";
1538
1539 unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
1540 : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
1541 unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
1542 : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
1543 llvm::errs() << NumUninitAnalysisFunctions
1544 << " functions analyzed for uninitialiazed variables\n"
1545 << " " << NumUninitAnalysisVariables << " variables analyzed.\n"
1546 << " " << AvgUninitVariablesPerFunction
1547 << " average variables per function.\n"
1548 << " " << MaxUninitAnalysisVariablesPerFunction
1549 << " max variables per function.\n"
1550 << " " << NumUninitAnalysisBlockVisits << " block visits.\n"
1551 << " " << AvgUninitBlockVisitsPerFunction
1552 << " average block visits per function.\n"
1553 << " " << MaxUninitAnalysisBlockVisitsPerFunction
1554 << " max block visits per function.\n";
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001555}