xref: /freebsd/contrib/llvm-project/clang/lib/Sema/JumpDiagnostics.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===--- JumpDiagnostics.cpp - Protected scope jump analysis ------*- C++ -*-=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the JumpScopeChecker class, which is used to diagnose
10 // jumps that enter a protected scope in an invalid way.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/Expr.h"
16 #include "clang/AST/ExprCXX.h"
17 #include "clang/AST/StmtCXX.h"
18 #include "clang/AST/StmtObjC.h"
19 #include "clang/AST/StmtOpenACC.h"
20 #include "clang/AST/StmtOpenMP.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "clang/Sema/SemaInternal.h"
23 #include "llvm/ADT/BitVector.h"
24 using namespace clang;
25 
26 namespace {
27 
28 /// JumpScopeChecker - This object is used by Sema to diagnose invalid jumps
29 /// into VLA and other protected scopes.  For example, this rejects:
30 ///    goto L;
31 ///    int a[n];
32 ///  L:
33 ///
34 /// We also detect jumps out of protected scopes when it's not possible to do
35 /// cleanups properly. Indirect jumps and ASM jumps can't do cleanups because
36 /// the target is unknown. Return statements with \c [[clang::musttail]] cannot
37 /// handle any cleanups due to the nature of a tail call.
38 class JumpScopeChecker {
39   Sema &S;
40 
41   /// Permissive - True when recovering from errors, in which case precautions
42   /// are taken to handle incomplete scope information.
43   const bool Permissive;
44 
45   /// GotoScope - This is a record that we use to keep track of all of the
46   /// scopes that are introduced by VLAs and other things that scope jumps like
47   /// gotos.  This scope tree has nothing to do with the source scope tree,
48   /// because you can have multiple VLA scopes per compound statement, and most
49   /// compound statements don't introduce any scopes.
50   struct GotoScope {
51     /// ParentScope - The index in ScopeMap of the parent scope.  This is 0 for
52     /// the parent scope is the function body.
53     unsigned ParentScope;
54 
55     /// InDiag - The note to emit if there is a jump into this scope.
56     unsigned InDiag;
57 
58     /// OutDiag - The note to emit if there is an indirect jump out
59     /// of this scope.  Direct jumps always clean up their current scope
60     /// in an orderly way.
61     unsigned OutDiag;
62 
63     /// Loc - Location to emit the diagnostic.
64     SourceLocation Loc;
65 
GotoScope__anon116d3ae30111::JumpScopeChecker::GotoScope66     GotoScope(unsigned parentScope, unsigned InDiag, unsigned OutDiag,
67               SourceLocation L)
68       : ParentScope(parentScope), InDiag(InDiag), OutDiag(OutDiag), Loc(L) {}
69   };
70 
71   SmallVector<GotoScope, 48> Scopes;
72   llvm::DenseMap<Stmt*, unsigned> LabelAndGotoScopes;
73   SmallVector<Stmt*, 16> Jumps;
74 
75   SmallVector<Stmt*, 4> IndirectJumps;
76   SmallVector<LabelDecl *, 4> IndirectJumpTargets;
77   SmallVector<AttributedStmt *, 4> MustTailStmts;
78 
79 public:
80   JumpScopeChecker(Stmt *Body, Sema &S);
81 private:
82   void BuildScopeInformation(Decl *D, unsigned &ParentScope);
83   void BuildScopeInformation(VarDecl *D, const BlockDecl *BDecl,
84                              unsigned &ParentScope);
85   void BuildScopeInformation(CompoundLiteralExpr *CLE, unsigned &ParentScope);
86   void BuildScopeInformation(Stmt *S, unsigned &origParentScope);
87 
88   void VerifyJumps();
89   void VerifyIndirectJumps();
90   void VerifyMustTailStmts();
91   void NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes);
92   void DiagnoseIndirectOrAsmJump(Stmt *IG, unsigned IGScope, LabelDecl *Target,
93                                  unsigned TargetScope);
94   void CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
95                  unsigned JumpDiag, unsigned JumpDiagWarning,
96                  unsigned JumpDiagCompat);
97   void CheckGotoStmt(GotoStmt *GS);
98   const Attr *GetMustTailAttr(AttributedStmt *AS);
99 
100   unsigned GetDeepestCommonScope(unsigned A, unsigned B);
101 };
102 } // end anonymous namespace
103 
104 #define CHECK_PERMISSIVE(x) (assert(Permissive || !(x)), (Permissive && (x)))
105 
JumpScopeChecker(Stmt * Body,Sema & s)106 JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s)
107     : S(s), Permissive(s.hasAnyUnrecoverableErrorsInThisFunction()) {
108   // Add a scope entry for function scope.
109   Scopes.push_back(GotoScope(~0U, ~0U, ~0U, SourceLocation()));
110 
111   // Build information for the top level compound statement, so that we have a
112   // defined scope record for every "goto" and label.
113   unsigned BodyParentScope = 0;
114   BuildScopeInformation(Body, BodyParentScope);
115 
116   // Check that all jumps we saw are kosher.
117   VerifyJumps();
118   VerifyIndirectJumps();
119   VerifyMustTailStmts();
120 }
121 
122 /// GetDeepestCommonScope - Finds the innermost scope enclosing the
123 /// two scopes.
GetDeepestCommonScope(unsigned A,unsigned B)124 unsigned JumpScopeChecker::GetDeepestCommonScope(unsigned A, unsigned B) {
125   while (A != B) {
126     // Inner scopes are created after outer scopes and therefore have
127     // higher indices.
128     if (A < B) {
129       assert(Scopes[B].ParentScope < B);
130       B = Scopes[B].ParentScope;
131     } else {
132       assert(Scopes[A].ParentScope < A);
133       A = Scopes[A].ParentScope;
134     }
135   }
136   return A;
137 }
138 
139 typedef std::pair<unsigned,unsigned> ScopePair;
140 
141 /// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
142 /// diagnostic that should be emitted if control goes over it. If not, return 0.
GetDiagForGotoScopeDecl(Sema & S,const Decl * D)143 static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {
144   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
145     unsigned InDiag = 0;
146     unsigned OutDiag = 0;
147 
148     if (VD->getType()->isVariablyModifiedType())
149       InDiag = diag::note_protected_by_vla;
150 
151     if (VD->hasAttr<BlocksAttr>())
152       return ScopePair(diag::note_protected_by___block,
153                        diag::note_exits___block);
154 
155     if (VD->hasAttr<CleanupAttr>())
156       return ScopePair(diag::note_protected_by_cleanup,
157                        diag::note_exits_cleanup);
158 
159     if (VD->hasLocalStorage()) {
160       switch (VD->getType().isDestructedType()) {
161       case QualType::DK_objc_strong_lifetime:
162         return ScopePair(diag::note_protected_by_objc_strong_init,
163                          diag::note_exits_objc_strong);
164 
165       case QualType::DK_objc_weak_lifetime:
166         return ScopePair(diag::note_protected_by_objc_weak_init,
167                          diag::note_exits_objc_weak);
168 
169       case QualType::DK_nontrivial_c_struct:
170         return ScopePair(diag::note_protected_by_non_trivial_c_struct_init,
171                          diag::note_exits_dtor);
172 
173       case QualType::DK_cxx_destructor:
174         OutDiag = diag::note_exits_dtor;
175         break;
176 
177       case QualType::DK_none:
178         break;
179       }
180     }
181 
182     if (const Expr *Init = VD->getInit();
183         VD->hasLocalStorage() && Init && !Init->containsErrors()) {
184       // C++11 [stmt.dcl]p3:
185       //   A program that jumps from a point where a variable with automatic
186       //   storage duration is not in scope to a point where it is in scope
187       //   is ill-formed unless the variable has scalar type, class type with
188       //   a trivial default constructor and a trivial destructor, a
189       //   cv-qualified version of one of these types, or an array of one of
190       //   the preceding types and is declared without an initializer.
191 
192       // C++03 [stmt.dcl.p3:
193       //   A program that jumps from a point where a local variable
194       //   with automatic storage duration is not in scope to a point
195       //   where it is in scope is ill-formed unless the variable has
196       //   POD type and is declared without an initializer.
197 
198       InDiag = diag::note_protected_by_variable_init;
199 
200       // For a variable of (array of) class type declared without an
201       // initializer, we will have call-style initialization and the initializer
202       // will be the CXXConstructExpr with no intervening nodes.
203       if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
204         const CXXConstructorDecl *Ctor = CCE->getConstructor();
205         if (Ctor->isTrivial() && Ctor->isDefaultConstructor() &&
206             VD->getInitStyle() == VarDecl::CallInit) {
207           if (OutDiag)
208             InDiag = diag::note_protected_by_variable_nontriv_destructor;
209           else if (!Ctor->getParent()->isPOD())
210             InDiag = diag::note_protected_by_variable_non_pod;
211           else
212             InDiag = 0;
213         }
214       }
215     }
216 
217     return ScopePair(InDiag, OutDiag);
218   }
219 
220   if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
221     if (TD->getUnderlyingType()->isVariablyModifiedType())
222       return ScopePair(isa<TypedefDecl>(TD)
223                            ? diag::note_protected_by_vla_typedef
224                            : diag::note_protected_by_vla_type_alias,
225                        0);
226   }
227 
228   return ScopePair(0U, 0U);
229 }
230 
231 /// Build scope information for a declaration that is part of a DeclStmt.
BuildScopeInformation(Decl * D,unsigned & ParentScope)232 void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {
233   // If this decl causes a new scope, push and switch to it.
234   std::pair<unsigned,unsigned> Diags = GetDiagForGotoScopeDecl(S, D);
235   if (Diags.first || Diags.second) {
236     Scopes.push_back(GotoScope(ParentScope, Diags.first, Diags.second,
237                                D->getLocation()));
238     ParentScope = Scopes.size()-1;
239   }
240 
241   // If the decl has an initializer, walk it with the potentially new
242   // scope we just installed.
243   if (VarDecl *VD = dyn_cast<VarDecl>(D))
244     if (Expr *Init = VD->getInit())
245       BuildScopeInformation(Init, ParentScope);
246 }
247 
248 /// Build scope information for a captured block literal variables.
BuildScopeInformation(VarDecl * D,const BlockDecl * BDecl,unsigned & ParentScope)249 void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
250                                              const BlockDecl *BDecl,
251                                              unsigned &ParentScope) {
252   // exclude captured __block variables; there's no destructor
253   // associated with the block literal for them.
254   if (D->hasAttr<BlocksAttr>())
255     return;
256   QualType T = D->getType();
257   QualType::DestructionKind destructKind = T.isDestructedType();
258   if (destructKind != QualType::DK_none) {
259     std::pair<unsigned,unsigned> Diags;
260     switch (destructKind) {
261       case QualType::DK_cxx_destructor:
262         Diags = ScopePair(diag::note_enters_block_captures_cxx_obj,
263                           diag::note_exits_block_captures_cxx_obj);
264         break;
265       case QualType::DK_objc_strong_lifetime:
266         Diags = ScopePair(diag::note_enters_block_captures_strong,
267                           diag::note_exits_block_captures_strong);
268         break;
269       case QualType::DK_objc_weak_lifetime:
270         Diags = ScopePair(diag::note_enters_block_captures_weak,
271                           diag::note_exits_block_captures_weak);
272         break;
273       case QualType::DK_nontrivial_c_struct:
274         Diags = ScopePair(diag::note_enters_block_captures_non_trivial_c_struct,
275                           diag::note_exits_block_captures_non_trivial_c_struct);
276         break;
277       case QualType::DK_none:
278         llvm_unreachable("non-lifetime captured variable");
279     }
280     SourceLocation Loc = D->getLocation();
281     if (Loc.isInvalid())
282       Loc = BDecl->getLocation();
283     Scopes.push_back(GotoScope(ParentScope,
284                                Diags.first, Diags.second, Loc));
285     ParentScope = Scopes.size()-1;
286   }
287 }
288 
289 /// Build scope information for compound literals of C struct types that are
290 /// non-trivial to destruct.
BuildScopeInformation(CompoundLiteralExpr * CLE,unsigned & ParentScope)291 void JumpScopeChecker::BuildScopeInformation(CompoundLiteralExpr *CLE,
292                                              unsigned &ParentScope) {
293   unsigned InDiag = diag::note_enters_compound_literal_scope;
294   unsigned OutDiag = diag::note_exits_compound_literal_scope;
295   Scopes.push_back(GotoScope(ParentScope, InDiag, OutDiag, CLE->getExprLoc()));
296   ParentScope = Scopes.size() - 1;
297 }
298 
299 /// BuildScopeInformation - The statements from CI to CE are known to form a
300 /// coherent VLA scope with a specified parent node.  Walk through the
301 /// statements, adding any labels or gotos to LabelAndGotoScopes and recursively
302 /// walking the AST as needed.
BuildScopeInformation(Stmt * S,unsigned & origParentScope)303 void JumpScopeChecker::BuildScopeInformation(Stmt *S,
304                                              unsigned &origParentScope) {
305   // If this is a statement, rather than an expression, scopes within it don't
306   // propagate out into the enclosing scope.  Otherwise we have to worry
307   // about block literals, which have the lifetime of their enclosing statement.
308   unsigned independentParentScope = origParentScope;
309   unsigned &ParentScope = ((isa<Expr>(S) && !isa<StmtExpr>(S))
310                             ? origParentScope : independentParentScope);
311 
312   unsigned StmtsToSkip = 0u;
313 
314   // If we found a label, remember that it is in ParentScope scope.
315   switch (S->getStmtClass()) {
316   case Stmt::AddrLabelExprClass:
317     IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
318     break;
319 
320   case Stmt::ObjCForCollectionStmtClass: {
321     auto *CS = cast<ObjCForCollectionStmt>(S);
322     unsigned Diag = diag::note_protected_by_objc_fast_enumeration;
323     unsigned NewParentScope = Scopes.size();
324     Scopes.push_back(GotoScope(ParentScope, Diag, 0, S->getBeginLoc()));
325     BuildScopeInformation(CS->getBody(), NewParentScope);
326     return;
327   }
328 
329   case Stmt::IndirectGotoStmtClass:
330     // "goto *&&lbl;" is a special case which we treat as equivalent
331     // to a normal goto.  In addition, we don't calculate scope in the
332     // operand (to avoid recording the address-of-label use), which
333     // works only because of the restricted set of expressions which
334     // we detect as constant targets.
335     if (cast<IndirectGotoStmt>(S)->getConstantTarget())
336       goto RecordJumpScope;
337 
338     LabelAndGotoScopes[S] = ParentScope;
339     IndirectJumps.push_back(S);
340     break;
341 
342   case Stmt::SwitchStmtClass:
343     // Evaluate the C++17 init stmt and condition variable
344     // before entering the scope of the switch statement.
345     if (Stmt *Init = cast<SwitchStmt>(S)->getInit()) {
346       BuildScopeInformation(Init, ParentScope);
347       ++StmtsToSkip;
348     }
349     if (VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable()) {
350       BuildScopeInformation(Var, ParentScope);
351       ++StmtsToSkip;
352     }
353     goto RecordJumpScope;
354 
355   case Stmt::GCCAsmStmtClass:
356     if (!cast<GCCAsmStmt>(S)->isAsmGoto())
357       break;
358     [[fallthrough]];
359 
360   case Stmt::GotoStmtClass:
361   RecordJumpScope:
362     // Remember both what scope a goto is in as well as the fact that we have
363     // it.  This makes the second scan not have to walk the AST again.
364     LabelAndGotoScopes[S] = ParentScope;
365     Jumps.push_back(S);
366     break;
367 
368   case Stmt::IfStmtClass: {
369     IfStmt *IS = cast<IfStmt>(S);
370     if (!(IS->isConstexpr() || IS->isConsteval() ||
371           IS->isObjCAvailabilityCheck()))
372       break;
373 
374     unsigned Diag = diag::note_protected_by_if_available;
375     if (IS->isConstexpr())
376       Diag = diag::note_protected_by_constexpr_if;
377     else if (IS->isConsteval())
378       Diag = diag::note_protected_by_consteval_if;
379 
380     if (VarDecl *Var = IS->getConditionVariable())
381       BuildScopeInformation(Var, ParentScope);
382 
383     // Cannot jump into the middle of the condition.
384     unsigned NewParentScope = Scopes.size();
385     Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc()));
386 
387     if (!IS->isConsteval())
388       BuildScopeInformation(IS->getCond(), NewParentScope);
389 
390     // Jumps into either arm of an 'if constexpr' are not allowed.
391     NewParentScope = Scopes.size();
392     Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc()));
393     BuildScopeInformation(IS->getThen(), NewParentScope);
394     if (Stmt *Else = IS->getElse()) {
395       NewParentScope = Scopes.size();
396       Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc()));
397       BuildScopeInformation(Else, NewParentScope);
398     }
399     return;
400   }
401 
402   case Stmt::CXXTryStmtClass: {
403     CXXTryStmt *TS = cast<CXXTryStmt>(S);
404     {
405       unsigned NewParentScope = Scopes.size();
406       Scopes.push_back(GotoScope(ParentScope,
407                                  diag::note_protected_by_cxx_try,
408                                  diag::note_exits_cxx_try,
409                                  TS->getSourceRange().getBegin()));
410       if (Stmt *TryBlock = TS->getTryBlock())
411         BuildScopeInformation(TryBlock, NewParentScope);
412     }
413 
414     // Jump from the catch into the try is not allowed either.
415     for (unsigned I = 0, E = TS->getNumHandlers(); I != E; ++I) {
416       CXXCatchStmt *CS = TS->getHandler(I);
417       unsigned NewParentScope = Scopes.size();
418       Scopes.push_back(GotoScope(ParentScope,
419                                  diag::note_protected_by_cxx_catch,
420                                  diag::note_exits_cxx_catch,
421                                  CS->getSourceRange().getBegin()));
422       BuildScopeInformation(CS->getHandlerBlock(), NewParentScope);
423     }
424     return;
425   }
426 
427   case Stmt::SEHTryStmtClass: {
428     SEHTryStmt *TS = cast<SEHTryStmt>(S);
429     {
430       unsigned NewParentScope = Scopes.size();
431       Scopes.push_back(GotoScope(ParentScope,
432                                  diag::note_protected_by_seh_try,
433                                  diag::note_exits_seh_try,
434                                  TS->getSourceRange().getBegin()));
435       if (Stmt *TryBlock = TS->getTryBlock())
436         BuildScopeInformation(TryBlock, NewParentScope);
437     }
438 
439     // Jump from __except or __finally into the __try are not allowed either.
440     if (SEHExceptStmt *Except = TS->getExceptHandler()) {
441       unsigned NewParentScope = Scopes.size();
442       Scopes.push_back(GotoScope(ParentScope,
443                                  diag::note_protected_by_seh_except,
444                                  diag::note_exits_seh_except,
445                                  Except->getSourceRange().getBegin()));
446       BuildScopeInformation(Except->getBlock(), NewParentScope);
447     } else if (SEHFinallyStmt *Finally = TS->getFinallyHandler()) {
448       unsigned NewParentScope = Scopes.size();
449       Scopes.push_back(GotoScope(ParentScope,
450                                  diag::note_protected_by_seh_finally,
451                                  diag::note_exits_seh_finally,
452                                  Finally->getSourceRange().getBegin()));
453       BuildScopeInformation(Finally->getBlock(), NewParentScope);
454     }
455 
456     return;
457   }
458 
459   case Stmt::DeclStmtClass: {
460     // If this is a declstmt with a VLA definition, it defines a scope from here
461     // to the end of the containing context.
462     DeclStmt *DS = cast<DeclStmt>(S);
463     // The decl statement creates a scope if any of the decls in it are VLAs
464     // or have the cleanup attribute.
465     for (auto *I : DS->decls())
466       BuildScopeInformation(I, origParentScope);
467     return;
468   }
469 
470   case Stmt::StmtExprClass: {
471     // [GNU]
472     // Jumping into a statement expression with goto or using
473     // a switch statement outside the statement expression with
474     // a case or default label inside the statement expression is not permitted.
475     // Jumping out of a statement expression is permitted.
476     StmtExpr *SE = cast<StmtExpr>(S);
477     unsigned NewParentScope = Scopes.size();
478     Scopes.push_back(GotoScope(ParentScope,
479                                diag::note_enters_statement_expression,
480                                /*OutDiag=*/0, SE->getBeginLoc()));
481     BuildScopeInformation(SE->getSubStmt(), NewParentScope);
482     return;
483   }
484 
485   case Stmt::ObjCAtTryStmtClass: {
486     // Disallow jumps into any part of an @try statement by pushing a scope and
487     // walking all sub-stmts in that scope.
488     ObjCAtTryStmt *AT = cast<ObjCAtTryStmt>(S);
489     // Recursively walk the AST for the @try part.
490     {
491       unsigned NewParentScope = Scopes.size();
492       Scopes.push_back(GotoScope(ParentScope,
493                                  diag::note_protected_by_objc_try,
494                                  diag::note_exits_objc_try,
495                                  AT->getAtTryLoc()));
496       if (Stmt *TryPart = AT->getTryBody())
497         BuildScopeInformation(TryPart, NewParentScope);
498     }
499 
500     // Jump from the catch to the finally or try is not valid.
501     for (ObjCAtCatchStmt *AC : AT->catch_stmts()) {
502       unsigned NewParentScope = Scopes.size();
503       Scopes.push_back(GotoScope(ParentScope,
504                                  diag::note_protected_by_objc_catch,
505                                  diag::note_exits_objc_catch,
506                                  AC->getAtCatchLoc()));
507       // @catches are nested and it isn't
508       BuildScopeInformation(AC->getCatchBody(), NewParentScope);
509     }
510 
511     // Jump from the finally to the try or catch is not valid.
512     if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) {
513       unsigned NewParentScope = Scopes.size();
514       Scopes.push_back(GotoScope(ParentScope,
515                                  diag::note_protected_by_objc_finally,
516                                  diag::note_exits_objc_finally,
517                                  AF->getAtFinallyLoc()));
518       BuildScopeInformation(AF, NewParentScope);
519     }
520 
521     return;
522   }
523 
524   case Stmt::ObjCAtSynchronizedStmtClass: {
525     // Disallow jumps into the protected statement of an @synchronized, but
526     // allow jumps into the object expression it protects.
527     ObjCAtSynchronizedStmt *AS = cast<ObjCAtSynchronizedStmt>(S);
528     // Recursively walk the AST for the @synchronized object expr, it is
529     // evaluated in the normal scope.
530     BuildScopeInformation(AS->getSynchExpr(), ParentScope);
531 
532     // Recursively walk the AST for the @synchronized part, protected by a new
533     // scope.
534     unsigned NewParentScope = Scopes.size();
535     Scopes.push_back(GotoScope(ParentScope,
536                                diag::note_protected_by_objc_synchronized,
537                                diag::note_exits_objc_synchronized,
538                                AS->getAtSynchronizedLoc()));
539     BuildScopeInformation(AS->getSynchBody(), NewParentScope);
540     return;
541   }
542 
543   case Stmt::ObjCAutoreleasePoolStmtClass: {
544     // Disallow jumps into the protected statement of an @autoreleasepool.
545     ObjCAutoreleasePoolStmt *AS = cast<ObjCAutoreleasePoolStmt>(S);
546     // Recursively walk the AST for the @autoreleasepool part, protected by a
547     // new scope.
548     unsigned NewParentScope = Scopes.size();
549     Scopes.push_back(GotoScope(ParentScope,
550                                diag::note_protected_by_objc_autoreleasepool,
551                                diag::note_exits_objc_autoreleasepool,
552                                AS->getAtLoc()));
553     BuildScopeInformation(AS->getSubStmt(), NewParentScope);
554     return;
555   }
556 
557   case Stmt::ExprWithCleanupsClass: {
558     // Disallow jumps past full-expressions that use blocks with
559     // non-trivial cleanups of their captures.  This is theoretically
560     // implementable but a lot of work which we haven't felt up to doing.
561     ExprWithCleanups *EWC = cast<ExprWithCleanups>(S);
562     for (unsigned i = 0, e = EWC->getNumObjects(); i != e; ++i) {
563       if (auto *BDecl = dyn_cast<BlockDecl *>(EWC->getObject(i)))
564         for (const auto &CI : BDecl->captures()) {
565           VarDecl *variable = CI.getVariable();
566           BuildScopeInformation(variable, BDecl, origParentScope);
567         }
568       else if (auto *CLE = dyn_cast<CompoundLiteralExpr *>(EWC->getObject(i)))
569         BuildScopeInformation(CLE, origParentScope);
570       else
571         llvm_unreachable("unexpected cleanup object type");
572     }
573     break;
574   }
575 
576   case Stmt::MaterializeTemporaryExprClass: {
577     // Disallow jumps out of scopes containing temporaries lifetime-extended to
578     // automatic storage duration.
579     MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S);
580     if (MTE->getStorageDuration() == SD_Automatic) {
581       const Expr *ExtendedObject =
582           MTE->getSubExpr()->skipRValueSubobjectAdjustments();
583       if (ExtendedObject->getType().isDestructedType()) {
584         Scopes.push_back(GotoScope(ParentScope, 0,
585                                    diag::note_exits_temporary_dtor,
586                                    ExtendedObject->getExprLoc()));
587         origParentScope = Scopes.size()-1;
588       }
589     }
590     break;
591   }
592 
593   case Stmt::CaseStmtClass:
594   case Stmt::DefaultStmtClass:
595   case Stmt::LabelStmtClass:
596     LabelAndGotoScopes[S] = ParentScope;
597     break;
598 
599   case Stmt::OpenACCComputeConstructClass: {
600     unsigned NewParentScope = Scopes.size();
601     OpenACCComputeConstruct *CC = cast<OpenACCComputeConstruct>(S);
602     Scopes.push_back(GotoScope(
603         ParentScope, diag::note_acc_branch_into_compute_construct,
604         diag::note_acc_branch_out_of_compute_construct, CC->getBeginLoc()));
605     // This can be 'null' if the 'body' is a break that we diagnosed, so no
606     // reason to put the scope into place.
607     if (CC->getStructuredBlock())
608       BuildScopeInformation(CC->getStructuredBlock(), NewParentScope);
609     return;
610   }
611 
612   case Stmt::OpenACCCombinedConstructClass: {
613     unsigned NewParentScope = Scopes.size();
614     OpenACCCombinedConstruct *CC = cast<OpenACCCombinedConstruct>(S);
615     Scopes.push_back(GotoScope(
616         ParentScope, diag::note_acc_branch_into_compute_construct,
617         diag::note_acc_branch_out_of_compute_construct, CC->getBeginLoc()));
618     // This can be 'null' if the 'body' is a break that we diagnosed, so no
619     // reason to put the scope into place.
620     if (CC->getLoop())
621       BuildScopeInformation(CC->getLoop(), NewParentScope);
622     return;
623   }
624 
625   default:
626     if (auto *ED = dyn_cast<OMPExecutableDirective>(S)) {
627       if (!ED->isStandaloneDirective()) {
628         unsigned NewParentScope = Scopes.size();
629         Scopes.emplace_back(ParentScope,
630                             diag::note_omp_protected_structured_block,
631                             diag::note_omp_exits_structured_block,
632                             ED->getStructuredBlock()->getBeginLoc());
633         BuildScopeInformation(ED->getStructuredBlock(), NewParentScope);
634         return;
635       }
636     }
637     break;
638   }
639 
640   for (Stmt *SubStmt : S->children()) {
641     if (!SubStmt)
642         continue;
643     if (StmtsToSkip) {
644       --StmtsToSkip;
645       continue;
646     }
647 
648     // Cases, labels, attributes, and defaults aren't "scope parents".  It's also
649     // important to handle these iteratively instead of recursively in
650     // order to avoid blowing out the stack.
651     while (true) {
652       Stmt *Next;
653       if (SwitchCase *SC = dyn_cast<SwitchCase>(SubStmt))
654         Next = SC->getSubStmt();
655       else if (LabelStmt *LS = dyn_cast<LabelStmt>(SubStmt))
656         Next = LS->getSubStmt();
657       else if (AttributedStmt *AS = dyn_cast<AttributedStmt>(SubStmt)) {
658         if (GetMustTailAttr(AS)) {
659           LabelAndGotoScopes[AS] = ParentScope;
660           MustTailStmts.push_back(AS);
661         }
662         Next = AS->getSubStmt();
663       } else
664         break;
665 
666       LabelAndGotoScopes[SubStmt] = ParentScope;
667       SubStmt = Next;
668     }
669 
670     // Recursively walk the AST.
671     BuildScopeInformation(SubStmt, ParentScope);
672   }
673 }
674 
675 /// VerifyJumps - Verify each element of the Jumps array to see if they are
676 /// valid, emitting diagnostics if not.
VerifyJumps()677 void JumpScopeChecker::VerifyJumps() {
678   while (!Jumps.empty()) {
679     Stmt *Jump = Jumps.pop_back_val();
680 
681     // With a goto,
682     if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
683       // The label may not have a statement if it's coming from inline MS ASM.
684       if (GS->getLabel()->getStmt()) {
685         CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(),
686                   diag::err_goto_into_protected_scope,
687                   diag::ext_goto_into_protected_scope,
688                   S.getLangOpts().CPlusPlus
689                       ? diag::warn_cxx98_compat_goto_into_protected_scope
690                       : diag::warn_cpp_compat_goto_into_protected_scope);
691       }
692       CheckGotoStmt(GS);
693       continue;
694     }
695 
696     // If an asm goto jumps to a different scope, things like destructors or
697     // initializers might not be run which may be suprising to users. Perhaps
698     // this behavior can be changed in the future, but today Clang will not
699     // generate such code. Produce a diagnostic instead. See also the
700     // discussion here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110728.
701     if (auto *G = dyn_cast<GCCAsmStmt>(Jump)) {
702       for (AddrLabelExpr *L : G->labels()) {
703         LabelDecl *LD = L->getLabel();
704         unsigned JumpScope = LabelAndGotoScopes[G];
705         unsigned TargetScope = LabelAndGotoScopes[LD->getStmt()];
706         if (JumpScope != TargetScope)
707           DiagnoseIndirectOrAsmJump(G, JumpScope, LD, TargetScope);
708       }
709       continue;
710     }
711 
712     // We only get indirect gotos here when they have a constant target.
713     if (IndirectGotoStmt *IGS = dyn_cast<IndirectGotoStmt>(Jump)) {
714       LabelDecl *Target = IGS->getConstantTarget();
715       CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(),
716                 diag::err_goto_into_protected_scope,
717                 diag::ext_goto_into_protected_scope,
718                 S.getLangOpts().CPlusPlus
719                     ? diag::warn_cxx98_compat_goto_into_protected_scope
720                     : diag::warn_cpp_compat_goto_into_protected_scope);
721       continue;
722     }
723 
724     SwitchStmt *SS = cast<SwitchStmt>(Jump);
725     for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
726          SC = SC->getNextSwitchCase()) {
727       if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(SC)))
728         continue;
729       SourceLocation Loc;
730       if (CaseStmt *CS = dyn_cast<CaseStmt>(SC))
731         Loc = CS->getBeginLoc();
732       else if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC))
733         Loc = DS->getBeginLoc();
734       else
735         Loc = SC->getBeginLoc();
736       CheckJump(SS, SC, Loc, diag::err_switch_into_protected_scope, 0,
737                 S.getLangOpts().CPlusPlus
738                     ? diag::warn_cxx98_compat_switch_into_protected_scope
739                     : diag::warn_cpp_compat_switch_into_protected_scope);
740     }
741   }
742 }
743 
744 /// VerifyIndirectJumps - Verify whether any possible indirect goto jump might
745 /// cross a protection boundary.  Unlike direct jumps, indirect goto jumps
746 /// count cleanups as protection boundaries: since there's no way to know where
747 /// the jump is going, we can't implicitly run the right cleanups the way we
748 /// can with direct jumps.  Thus, an indirect/asm jump is "trivial" if it
749 /// bypasses no initializations and no teardowns.  More formally, an
750 /// indirect/asm jump from A to B is trivial if the path out from A to DCA(A,B)
751 /// is trivial and the path in from DCA(A,B) to B is trivial, where DCA(A,B) is
752 /// the deepest common ancestor of A and B.  Jump-triviality is transitive but
753 /// asymmetric.
754 ///
755 /// A path in is trivial if none of the entered scopes have an InDiag.
756 /// A path out is trivial is none of the exited scopes have an OutDiag.
757 ///
758 /// Under these definitions, this function checks that the indirect
759 /// jump between A and B is trivial for every indirect goto statement A
760 /// and every label B whose address was taken in the function.
VerifyIndirectJumps()761 void JumpScopeChecker::VerifyIndirectJumps() {
762   if (IndirectJumps.empty())
763     return;
764   // If there aren't any address-of-label expressions in this function,
765   // complain about the first indirect goto.
766   if (IndirectJumpTargets.empty()) {
767     S.Diag(IndirectJumps[0]->getBeginLoc(),
768            diag::err_indirect_goto_without_addrlabel);
769     return;
770   }
771   // Collect a single representative of every scope containing an indirect
772   // goto.  For most code bases, this substantially cuts down on the number of
773   // jump sites we'll have to consider later.
774   using JumpScope = std::pair<unsigned, Stmt *>;
775   SmallVector<JumpScope, 32> JumpScopes;
776   {
777     llvm::DenseMap<unsigned, Stmt*> JumpScopesMap;
778     for (Stmt *IG : IndirectJumps) {
779       if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(IG)))
780         continue;
781       unsigned IGScope = LabelAndGotoScopes[IG];
782       JumpScopesMap.try_emplace(IGScope, IG);
783     }
784     JumpScopes.reserve(JumpScopesMap.size());
785     for (auto &Pair : JumpScopesMap)
786       JumpScopes.emplace_back(Pair);
787   }
788 
789   // Collect a single representative of every scope containing a
790   // label whose address was taken somewhere in the function.
791   // For most code bases, there will be only one such scope.
792   llvm::DenseMap<unsigned, LabelDecl*> TargetScopes;
793   for (LabelDecl *TheLabel : IndirectJumpTargets) {
794     if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(TheLabel->getStmt())))
795       continue;
796     unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()];
797     TargetScopes.try_emplace(LabelScope, TheLabel);
798   }
799 
800   // For each target scope, make sure it's trivially reachable from
801   // every scope containing a jump site.
802   //
803   // A path between scopes always consists of exitting zero or more
804   // scopes, then entering zero or more scopes.  We build a set of
805   // of scopes S from which the target scope can be trivially
806   // entered, then verify that every jump scope can be trivially
807   // exitted to reach a scope in S.
808   llvm::BitVector Reachable(Scopes.size(), false);
809   for (auto [TargetScope, TargetLabel] : TargetScopes) {
810     Reachable.reset();
811 
812     // Mark all the enclosing scopes from which you can safely jump
813     // into the target scope.  'Min' will end up being the index of
814     // the shallowest such scope.
815     unsigned Min = TargetScope;
816     while (true) {
817       Reachable.set(Min);
818 
819       // Don't go beyond the outermost scope.
820       if (Min == 0) break;
821 
822       // Stop if we can't trivially enter the current scope.
823       if (Scopes[Min].InDiag) break;
824 
825       Min = Scopes[Min].ParentScope;
826     }
827 
828     // Walk through all the jump sites, checking that they can trivially
829     // reach this label scope.
830     for (auto [JumpScope, JumpStmt] : JumpScopes) {
831       unsigned Scope = JumpScope;
832       // Walk out the "scope chain" for this scope, looking for a scope
833       // we've marked reachable.  For well-formed code this amortizes
834       // to O(JumpScopes.size() / Scopes.size()):  we only iterate
835       // when we see something unmarked, and in well-formed code we
836       // mark everything we iterate past.
837       bool IsReachable = false;
838       while (true) {
839         if (Reachable.test(Scope)) {
840           // If we find something reachable, mark all the scopes we just
841           // walked through as reachable.
842           for (unsigned S = JumpScope; S != Scope; S = Scopes[S].ParentScope)
843             Reachable.set(S);
844           IsReachable = true;
845           break;
846         }
847 
848         // Don't walk out if we've reached the top-level scope or we've
849         // gotten shallower than the shallowest reachable scope.
850         if (Scope == 0 || Scope < Min) break;
851 
852         // Don't walk out through an out-diagnostic.
853         if (Scopes[Scope].OutDiag) break;
854 
855         Scope = Scopes[Scope].ParentScope;
856       }
857 
858       // Only diagnose if we didn't find something.
859       if (IsReachable) continue;
860 
861       DiagnoseIndirectOrAsmJump(JumpStmt, JumpScope, TargetLabel, TargetScope);
862     }
863   }
864 }
865 
866 /// Return true if a particular error+note combination must be downgraded to a
867 /// warning in Microsoft mode.
IsMicrosoftJumpWarning(unsigned JumpDiag,unsigned InDiagNote)868 static bool IsMicrosoftJumpWarning(unsigned JumpDiag, unsigned InDiagNote) {
869   return (JumpDiag == diag::err_goto_into_protected_scope &&
870          (InDiagNote == diag::note_protected_by_variable_init ||
871           InDiagNote == diag::note_protected_by_variable_nontriv_destructor));
872 }
873 
874 /// Return true if a particular note should be downgraded to a compatibility
875 /// warning in C++11 mode.
IsCXX98CompatWarning(Sema & S,unsigned InDiagNote)876 static bool IsCXX98CompatWarning(Sema &S, unsigned InDiagNote) {
877   return S.getLangOpts().CPlusPlus11 &&
878          InDiagNote == diag::note_protected_by_variable_non_pod;
879 }
880 
881 /// Returns true if a particular note should be a C++ compatibility warning in
882 /// C mode with -Wc++-compat.
IsCppCompatWarning(Sema & S,unsigned InDiagNote)883 static bool IsCppCompatWarning(Sema &S, unsigned InDiagNote) {
884   return !S.getLangOpts().CPlusPlus &&
885          InDiagNote == diag::note_protected_by_variable_init;
886 }
887 
888 /// Produce primary diagnostic for an indirect jump statement.
DiagnoseIndirectOrAsmJumpStmt(Sema & S,Stmt * Jump,LabelDecl * Target,bool & Diagnosed)889 static void DiagnoseIndirectOrAsmJumpStmt(Sema &S, Stmt *Jump,
890                                           LabelDecl *Target, bool &Diagnosed) {
891   if (Diagnosed)
892     return;
893   bool IsAsmGoto = isa<GCCAsmStmt>(Jump);
894   S.Diag(Jump->getBeginLoc(), diag::err_indirect_goto_in_protected_scope)
895       << IsAsmGoto;
896   S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target)
897       << IsAsmGoto;
898   Diagnosed = true;
899 }
900 
901 /// Produce note diagnostics for a jump into a protected scope.
NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes)902 void JumpScopeChecker::NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes) {
903   if (CHECK_PERMISSIVE(ToScopes.empty()))
904     return;
905   for (unsigned I = 0, E = ToScopes.size(); I != E; ++I)
906     if (Scopes[ToScopes[I]].InDiag)
907       S.Diag(Scopes[ToScopes[I]].Loc, Scopes[ToScopes[I]].InDiag);
908 }
909 
910 /// Diagnose an indirect jump which is known to cross scopes.
DiagnoseIndirectOrAsmJump(Stmt * Jump,unsigned JumpScope,LabelDecl * Target,unsigned TargetScope)911 void JumpScopeChecker::DiagnoseIndirectOrAsmJump(Stmt *Jump, unsigned JumpScope,
912                                                  LabelDecl *Target,
913                                                  unsigned TargetScope) {
914   if (CHECK_PERMISSIVE(JumpScope == TargetScope))
915     return;
916 
917   unsigned Common = GetDeepestCommonScope(JumpScope, TargetScope);
918   bool Diagnosed = false;
919 
920   // Walk out the scope chain until we reach the common ancestor.
921   for (unsigned I = JumpScope; I != Common; I = Scopes[I].ParentScope)
922     if (Scopes[I].OutDiag) {
923       DiagnoseIndirectOrAsmJumpStmt(S, Jump, Target, Diagnosed);
924       S.Diag(Scopes[I].Loc, Scopes[I].OutDiag);
925     }
926 
927   SmallVector<unsigned, 10> ToScopesCXX98Compat, ToScopesCppCompat;
928 
929   // Now walk into the scopes containing the label whose address was taken.
930   for (unsigned I = TargetScope; I != Common; I = Scopes[I].ParentScope)
931     if (IsCXX98CompatWarning(S, Scopes[I].InDiag))
932       ToScopesCXX98Compat.push_back(I);
933     else if (IsCppCompatWarning(S, Scopes[I].InDiag))
934       ToScopesCppCompat.push_back(I);
935     else if (Scopes[I].InDiag) {
936       DiagnoseIndirectOrAsmJumpStmt(S, Jump, Target, Diagnosed);
937       S.Diag(Scopes[I].Loc, Scopes[I].InDiag);
938     }
939 
940   // Diagnose this jump if it would be ill-formed in C++[98].
941   if (!Diagnosed) {
942     bool IsAsmGoto = isa<GCCAsmStmt>(Jump);
943     auto Diag = [&](unsigned DiagId, const SmallVectorImpl<unsigned> &Notes) {
944       S.Diag(Jump->getBeginLoc(), DiagId) << IsAsmGoto;
945       S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target)
946           << IsAsmGoto;
947       NoteJumpIntoScopes(Notes);
948     };
949     if (!ToScopesCXX98Compat.empty())
950       Diag(diag::warn_cxx98_compat_indirect_goto_in_protected_scope,
951            ToScopesCXX98Compat);
952     else if (!ToScopesCppCompat.empty())
953       Diag(diag::warn_cpp_compat_indirect_goto_in_protected_scope,
954            ToScopesCppCompat);
955   }
956 }
957 
958 /// CheckJump - Validate that the specified jump statement is valid: that it is
959 /// jumping within or out of its current scope, not into a deeper one.
CheckJump(Stmt * From,Stmt * To,SourceLocation DiagLoc,unsigned JumpDiagError,unsigned JumpDiagWarning,unsigned JumpDiagCompat)960 void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
961                                  unsigned JumpDiagError,
962                                  unsigned JumpDiagWarning,
963                                  unsigned JumpDiagCompat) {
964   if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(From)))
965     return;
966   if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(To)))
967     return;
968 
969   unsigned FromScope = LabelAndGotoScopes[From];
970   unsigned ToScope = LabelAndGotoScopes[To];
971 
972   // Common case: exactly the same scope, which is fine.
973   if (FromScope == ToScope) return;
974 
975   // Warn on gotos out of __finally blocks.
976   if (isa<GotoStmt>(From) || isa<IndirectGotoStmt>(From)) {
977     // If FromScope > ToScope, FromScope is more nested and the jump goes to a
978     // less nested scope.  Check if it crosses a __finally along the way.
979     for (unsigned I = FromScope; I > ToScope; I = Scopes[I].ParentScope) {
980       if (Scopes[I].InDiag == diag::note_protected_by_seh_finally) {
981         S.Diag(From->getBeginLoc(), diag::warn_jump_out_of_seh_finally);
982         break;
983       } else if (Scopes[I].InDiag ==
984                  diag::note_omp_protected_structured_block) {
985         S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
986         S.Diag(To->getBeginLoc(), diag::note_omp_exits_structured_block);
987         break;
988       } else if (Scopes[I].InDiag ==
989                  diag::note_acc_branch_into_compute_construct) {
990         S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
991         S.Diag(Scopes[I].Loc, diag::note_acc_branch_out_of_compute_construct);
992         return;
993       }
994     }
995   }
996 
997   unsigned CommonScope = GetDeepestCommonScope(FromScope, ToScope);
998 
999   // It's okay to jump out from a nested scope.
1000   if (CommonScope == ToScope) return;
1001 
1002   // Pull out (and reverse) any scopes we might need to diagnose skipping.
1003   SmallVector<unsigned, 10> ToScopesCompat;
1004   SmallVector<unsigned, 10> ToScopesError;
1005   SmallVector<unsigned, 10> ToScopesWarning;
1006   for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope) {
1007     if (S.getLangOpts().MSVCCompat && S.getLangOpts().CPlusPlus &&
1008         JumpDiagWarning != 0 &&
1009         IsMicrosoftJumpWarning(JumpDiagError, Scopes[I].InDiag))
1010       ToScopesWarning.push_back(I);
1011     else if (IsCXX98CompatWarning(S, Scopes[I].InDiag) ||
1012              IsCppCompatWarning(S, Scopes[I].InDiag))
1013       ToScopesCompat.push_back(I);
1014     else if (Scopes[I].InDiag)
1015       ToScopesError.push_back(I);
1016   }
1017 
1018   // Handle warnings.
1019   if (!ToScopesWarning.empty()) {
1020     S.Diag(DiagLoc, JumpDiagWarning);
1021     NoteJumpIntoScopes(ToScopesWarning);
1022     assert(isa<LabelStmt>(To));
1023     LabelStmt *Label = cast<LabelStmt>(To);
1024     Label->setSideEntry(true);
1025   }
1026 
1027   // Handle errors.
1028   if (!ToScopesError.empty()) {
1029     S.Diag(DiagLoc, JumpDiagError);
1030     NoteJumpIntoScopes(ToScopesError);
1031   }
1032 
1033   // Handle -Wc++98-compat or -Wc++-compat warnings if the jump is well-formed.
1034   if (ToScopesError.empty() && !ToScopesCompat.empty()) {
1035     S.Diag(DiagLoc, JumpDiagCompat);
1036     NoteJumpIntoScopes(ToScopesCompat);
1037   }
1038 }
1039 
CheckGotoStmt(GotoStmt * GS)1040 void JumpScopeChecker::CheckGotoStmt(GotoStmt *GS) {
1041   if (GS->getLabel()->isMSAsmLabel()) {
1042     S.Diag(GS->getGotoLoc(), diag::err_goto_ms_asm_label)
1043         << GS->getLabel()->getIdentifier();
1044     S.Diag(GS->getLabel()->getLocation(), diag::note_goto_ms_asm_label)
1045         << GS->getLabel()->getIdentifier();
1046   }
1047 }
1048 
VerifyMustTailStmts()1049 void JumpScopeChecker::VerifyMustTailStmts() {
1050   for (AttributedStmt *AS : MustTailStmts) {
1051     for (unsigned I = LabelAndGotoScopes[AS]; I; I = Scopes[I].ParentScope) {
1052       if (Scopes[I].OutDiag) {
1053         S.Diag(AS->getBeginLoc(), diag::err_musttail_scope);
1054         S.Diag(Scopes[I].Loc, Scopes[I].OutDiag);
1055       }
1056     }
1057   }
1058 }
1059 
GetMustTailAttr(AttributedStmt * AS)1060 const Attr *JumpScopeChecker::GetMustTailAttr(AttributedStmt *AS) {
1061   ArrayRef<const Attr *> Attrs = AS->getAttrs();
1062   const auto *Iter =
1063       llvm::find_if(Attrs, [](const Attr *A) { return isa<MustTailAttr>(A); });
1064   return Iter != Attrs.end() ? *Iter : nullptr;
1065 }
1066 
DiagnoseInvalidJumps(Stmt * Body)1067 void Sema::DiagnoseInvalidJumps(Stmt *Body) {
1068   (void)JumpScopeChecker(Body, *this);
1069 }
1070