Lines Matching +full:diag +full:- +full:version
1 //===--- JumpDiagnostics.cpp - Protected scope jump analysis ------*- C++ -*-=//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
28 /// JumpScopeChecker - This object is used by Sema to diagnose invalid jumps
41 /// Permissive - True when recovering from errors, in which case precautions
45 /// GotoScope - This is a record that we use to keep track of all of the
51 /// ParentScope - The index in ScopeMap of the parent scope. This is 0 for
55 /// InDiag - The note to emit if there is a jump into this scope.
58 /// OutDiag - The note to emit if there is an indirect jump out
63 /// Loc - Location to emit the diagnostic.
122 /// GetDeepestCommonScope - Finds the innermost scope enclosing the
141 /// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
148 if (VD->getType()->isVariablyModifiedType()) in GetDiagForGotoScopeDecl()
149 InDiag = diag::note_protected_by_vla; in GetDiagForGotoScopeDecl()
151 if (VD->hasAttr<BlocksAttr>()) in GetDiagForGotoScopeDecl()
152 return ScopePair(diag::note_protected_by___block, in GetDiagForGotoScopeDecl()
153 diag::note_exits___block); in GetDiagForGotoScopeDecl()
155 if (VD->hasAttr<CleanupAttr>()) in GetDiagForGotoScopeDecl()
156 return ScopePair(diag::note_protected_by_cleanup, in GetDiagForGotoScopeDecl()
157 diag::note_exits_cleanup); in GetDiagForGotoScopeDecl()
159 if (VD->hasLocalStorage()) { in GetDiagForGotoScopeDecl()
160 switch (VD->getType().isDestructedType()) { in GetDiagForGotoScopeDecl()
162 return ScopePair(diag::note_protected_by_objc_strong_init, in GetDiagForGotoScopeDecl()
163 diag::note_exits_objc_strong); in GetDiagForGotoScopeDecl()
166 return ScopePair(diag::note_protected_by_objc_weak_init, in GetDiagForGotoScopeDecl()
167 diag::note_exits_objc_weak); in GetDiagForGotoScopeDecl()
170 return ScopePair(diag::note_protected_by_non_trivial_c_struct_init, in GetDiagForGotoScopeDecl()
171 diag::note_exits_dtor); in GetDiagForGotoScopeDecl()
174 OutDiag = diag::note_exits_dtor; in GetDiagForGotoScopeDecl()
182 const Expr *Init = VD->getInit(); in GetDiagForGotoScopeDecl()
183 if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init && in GetDiagForGotoScopeDecl()
184 !Init->containsErrors()) { in GetDiagForGotoScopeDecl()
188 // is ill-formed unless the variable has scalar type, class type with in GetDiagForGotoScopeDecl()
190 // cv-qualified version of one of these types, or an array of one of in GetDiagForGotoScopeDecl()
196 // where it is in scope is ill-formed unless the variable has in GetDiagForGotoScopeDecl()
199 InDiag = diag::note_protected_by_variable_init; in GetDiagForGotoScopeDecl()
202 // initializer, we will have call-style initialization and the initializer in GetDiagForGotoScopeDecl()
205 const CXXConstructorDecl *Ctor = CCE->getConstructor(); in GetDiagForGotoScopeDecl()
206 if (Ctor->isTrivial() && Ctor->isDefaultConstructor() && in GetDiagForGotoScopeDecl()
207 VD->getInitStyle() == VarDecl::CallInit) { in GetDiagForGotoScopeDecl()
209 InDiag = diag::note_protected_by_variable_nontriv_destructor; in GetDiagForGotoScopeDecl()
210 else if (!Ctor->getParent()->isPOD()) in GetDiagForGotoScopeDecl()
211 InDiag = diag::note_protected_by_variable_non_pod; in GetDiagForGotoScopeDecl()
222 if (TD->getUnderlyingType()->isVariablyModifiedType()) in GetDiagForGotoScopeDecl()
224 ? diag::note_protected_by_vla_typedef in GetDiagForGotoScopeDecl()
225 : diag::note_protected_by_vla_type_alias, in GetDiagForGotoScopeDecl()
238 D->getLocation())); in BuildScopeInformation()
239 ParentScope = Scopes.size()-1; in BuildScopeInformation()
245 if (Expr *Init = VD->getInit()) in BuildScopeInformation()
255 if (D->hasAttr<BlocksAttr>()) in BuildScopeInformation()
257 QualType T = D->getType(); in BuildScopeInformation()
263 Diags = ScopePair(diag::note_enters_block_captures_cxx_obj, in BuildScopeInformation()
264 diag::note_exits_block_captures_cxx_obj); in BuildScopeInformation()
267 Diags = ScopePair(diag::note_enters_block_captures_strong, in BuildScopeInformation()
268 diag::note_exits_block_captures_strong); in BuildScopeInformation()
271 Diags = ScopePair(diag::note_enters_block_captures_weak, in BuildScopeInformation()
272 diag::note_exits_block_captures_weak); in BuildScopeInformation()
275 Diags = ScopePair(diag::note_enters_block_captures_non_trivial_c_struct, in BuildScopeInformation()
276 diag::note_exits_block_captures_non_trivial_c_struct); in BuildScopeInformation()
279 llvm_unreachable("non-lifetime captured variable"); in BuildScopeInformation()
281 SourceLocation Loc = D->getLocation(); in BuildScopeInformation()
283 Loc = BDecl->getLocation(); in BuildScopeInformation()
286 ParentScope = Scopes.size()-1; in BuildScopeInformation()
291 /// non-trivial to destruct.
294 unsigned InDiag = diag::note_enters_compound_literal_scope; in BuildScopeInformation()
295 unsigned OutDiag = diag::note_exits_compound_literal_scope; in BuildScopeInformation()
296 Scopes.push_back(GotoScope(ParentScope, InDiag, OutDiag, CLE->getExprLoc())); in BuildScopeInformation()
297 ParentScope = Scopes.size() - 1; in BuildScopeInformation()
300 /// BuildScopeInformation - The statements from CI to CE are known to form a
316 switch (S->getStmtClass()) { in BuildScopeInformation()
318 IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel()); in BuildScopeInformation()
323 unsigned Diag = diag::note_protected_by_objc_fast_enumeration; in BuildScopeInformation() local
325 Scopes.push_back(GotoScope(ParentScope, Diag, 0, S->getBeginLoc())); in BuildScopeInformation()
326 BuildScopeInformation(CS->getBody(), NewParentScope); in BuildScopeInformation()
333 // operand (to avoid recording the address-of-label use), which in BuildScopeInformation()
336 if (cast<IndirectGotoStmt>(S)->getConstantTarget()) in BuildScopeInformation()
346 if (Stmt *Init = cast<SwitchStmt>(S)->getInit()) { in BuildScopeInformation()
350 if (VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable()) { in BuildScopeInformation()
357 if (!cast<GCCAsmStmt>(S)->isAsmGoto()) in BuildScopeInformation()
371 if (!(IS->isConstexpr() || IS->isConsteval() || in BuildScopeInformation()
372 IS->isObjCAvailabilityCheck())) in BuildScopeInformation()
375 unsigned Diag = diag::note_protected_by_if_available; in BuildScopeInformation() local
376 if (IS->isConstexpr()) in BuildScopeInformation()
377 Diag = diag::note_protected_by_constexpr_if; in BuildScopeInformation()
378 else if (IS->isConsteval()) in BuildScopeInformation()
379 Diag = diag::note_protected_by_consteval_if; in BuildScopeInformation()
381 if (VarDecl *Var = IS->getConditionVariable()) in BuildScopeInformation()
386 Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc())); in BuildScopeInformation()
388 if (!IS->isConsteval()) in BuildScopeInformation()
389 BuildScopeInformation(IS->getCond(), NewParentScope); in BuildScopeInformation()
393 Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc())); in BuildScopeInformation()
394 BuildScopeInformation(IS->getThen(), NewParentScope); in BuildScopeInformation()
395 if (Stmt *Else = IS->getElse()) { in BuildScopeInformation()
397 Scopes.push_back(GotoScope(ParentScope, Diag, 0, IS->getBeginLoc())); in BuildScopeInformation()
408 diag::note_protected_by_cxx_try, in BuildScopeInformation()
409 diag::note_exits_cxx_try, in BuildScopeInformation()
410 TS->getSourceRange().getBegin())); in BuildScopeInformation()
411 if (Stmt *TryBlock = TS->getTryBlock()) in BuildScopeInformation()
416 for (unsigned I = 0, E = TS->getNumHandlers(); I != E; ++I) { in BuildScopeInformation()
417 CXXCatchStmt *CS = TS->getHandler(I); in BuildScopeInformation()
420 diag::note_protected_by_cxx_catch, in BuildScopeInformation()
421 diag::note_exits_cxx_catch, in BuildScopeInformation()
422 CS->getSourceRange().getBegin())); in BuildScopeInformation()
423 BuildScopeInformation(CS->getHandlerBlock(), NewParentScope); in BuildScopeInformation()
433 diag::note_protected_by_seh_try, in BuildScopeInformation()
434 diag::note_exits_seh_try, in BuildScopeInformation()
435 TS->getSourceRange().getBegin())); in BuildScopeInformation()
436 if (Stmt *TryBlock = TS->getTryBlock()) in BuildScopeInformation()
441 if (SEHExceptStmt *Except = TS->getExceptHandler()) { in BuildScopeInformation()
444 diag::note_protected_by_seh_except, in BuildScopeInformation()
445 diag::note_exits_seh_except, in BuildScopeInformation()
446 Except->getSourceRange().getBegin())); in BuildScopeInformation()
447 BuildScopeInformation(Except->getBlock(), NewParentScope); in BuildScopeInformation()
448 } else if (SEHFinallyStmt *Finally = TS->getFinallyHandler()) { in BuildScopeInformation()
451 diag::note_protected_by_seh_finally, in BuildScopeInformation()
452 diag::note_exits_seh_finally, in BuildScopeInformation()
453 Finally->getSourceRange().getBegin())); in BuildScopeInformation()
454 BuildScopeInformation(Finally->getBlock(), NewParentScope); in BuildScopeInformation()
466 for (auto *I : DS->decls()) in BuildScopeInformation()
480 diag::note_enters_statement_expression, in BuildScopeInformation()
481 /*OutDiag=*/0, SE->getBeginLoc())); in BuildScopeInformation()
482 BuildScopeInformation(SE->getSubStmt(), NewParentScope); in BuildScopeInformation()
488 // walking all sub-stmts in that scope. in BuildScopeInformation()
494 diag::note_protected_by_objc_try, in BuildScopeInformation()
495 diag::note_exits_objc_try, in BuildScopeInformation()
496 AT->getAtTryLoc())); in BuildScopeInformation()
497 if (Stmt *TryPart = AT->getTryBody()) in BuildScopeInformation()
502 for (ObjCAtCatchStmt *AC : AT->catch_stmts()) { in BuildScopeInformation()
505 diag::note_protected_by_objc_catch, in BuildScopeInformation()
506 diag::note_exits_objc_catch, in BuildScopeInformation()
507 AC->getAtCatchLoc())); in BuildScopeInformation()
509 BuildScopeInformation(AC->getCatchBody(), NewParentScope); in BuildScopeInformation()
513 if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) { in BuildScopeInformation()
516 diag::note_protected_by_objc_finally, in BuildScopeInformation()
517 diag::note_exits_objc_finally, in BuildScopeInformation()
518 AF->getAtFinallyLoc())); in BuildScopeInformation()
531 BuildScopeInformation(AS->getSynchExpr(), ParentScope); in BuildScopeInformation()
537 diag::note_protected_by_objc_synchronized, in BuildScopeInformation()
538 diag::note_exits_objc_synchronized, in BuildScopeInformation()
539 AS->getAtSynchronizedLoc())); in BuildScopeInformation()
540 BuildScopeInformation(AS->getSynchBody(), NewParentScope); in BuildScopeInformation()
551 diag::note_protected_by_objc_autoreleasepool, in BuildScopeInformation()
552 diag::note_exits_objc_autoreleasepool, in BuildScopeInformation()
553 AS->getAtLoc())); in BuildScopeInformation()
554 BuildScopeInformation(AS->getSubStmt(), NewParentScope); in BuildScopeInformation()
559 // Disallow jumps past full-expressions that use blocks with in BuildScopeInformation()
560 // non-trivial cleanups of their captures. This is theoretically in BuildScopeInformation()
563 for (unsigned i = 0, e = EWC->getNumObjects(); i != e; ++i) { in BuildScopeInformation()
564 if (auto *BDecl = EWC->getObject(i).dyn_cast<BlockDecl *>()) in BuildScopeInformation()
565 for (const auto &CI : BDecl->captures()) { in BuildScopeInformation()
569 else if (auto *CLE = EWC->getObject(i).dyn_cast<CompoundLiteralExpr *>()) in BuildScopeInformation()
578 // Disallow jumps out of scopes containing temporaries lifetime-extended to in BuildScopeInformation()
581 if (MTE->getStorageDuration() == SD_Automatic) { in BuildScopeInformation()
583 MTE->getSubExpr()->skipRValueSubobjectAdjustments(); in BuildScopeInformation()
584 if (ExtendedObject->getType().isDestructedType()) { in BuildScopeInformation()
586 diag::note_exits_temporary_dtor, in BuildScopeInformation()
587 ExtendedObject->getExprLoc())); in BuildScopeInformation()
588 origParentScope = Scopes.size()-1; in BuildScopeInformation()
613 ParentScope, diag::note_acc_branch_into_compute_construct, in BuildScopeInformation()
614 diag::note_acc_branch_out_of_compute_construct, CC->getBeginLoc())); in BuildScopeInformation()
615 BuildScopeInformation(CC->getStructuredBlock(), NewParentScope); in BuildScopeInformation()
621 if (!ED->isStandaloneDirective()) { in BuildScopeInformation()
624 diag::note_omp_protected_structured_block, in BuildScopeInformation()
625 diag::note_omp_exits_structured_block, in BuildScopeInformation()
626 ED->getStructuredBlock()->getBeginLoc()); in BuildScopeInformation()
627 BuildScopeInformation(ED->getStructuredBlock(), NewParentScope); in BuildScopeInformation()
634 for (Stmt *SubStmt : S->children()) { in BuildScopeInformation()
638 --StmtsToSkip; in BuildScopeInformation()
648 Next = SC->getSubStmt(); in BuildScopeInformation()
650 Next = LS->getSubStmt(); in BuildScopeInformation()
663 /// VerifyJumps - Verify each element of the Jumps array to see if they are
672 if (GS->getLabel()->getStmt()) { in VerifyJumps()
673 CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(), in VerifyJumps()
674 diag::err_goto_into_protected_scope, in VerifyJumps()
675 diag::ext_goto_into_protected_scope, in VerifyJumps()
676 diag::warn_cxx98_compat_goto_into_protected_scope); in VerifyJumps()
688 for (AddrLabelExpr *L : G->labels()) { in VerifyJumps()
689 LabelDecl *LD = L->getLabel(); in VerifyJumps()
691 unsigned TargetScope = LabelAndGotoScopes[LD->getStmt()]; in VerifyJumps()
700 LabelDecl *Target = IGS->getConstantTarget(); in VerifyJumps()
701 CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(), in VerifyJumps()
702 diag::err_goto_into_protected_scope, in VerifyJumps()
703 diag::ext_goto_into_protected_scope, in VerifyJumps()
704 diag::warn_cxx98_compat_goto_into_protected_scope); in VerifyJumps()
709 for (SwitchCase *SC = SS->getSwitchCaseList(); SC; in VerifyJumps()
710 SC = SC->getNextSwitchCase()) { in VerifyJumps()
715 Loc = CS->getBeginLoc(); in VerifyJumps()
717 Loc = DS->getBeginLoc(); in VerifyJumps()
719 Loc = SC->getBeginLoc(); in VerifyJumps()
720 CheckJump(SS, SC, Loc, diag::err_switch_into_protected_scope, 0, in VerifyJumps()
721 diag::warn_cxx98_compat_switch_into_protected_scope); in VerifyJumps()
726 /// VerifyIndirectJumps - Verify whether any possible indirect goto jump might
734 /// the deepest common ancestor of A and B. Jump-triviality is transitive but
746 // If there aren't any address-of-label expressions in this function, in VerifyIndirectJumps()
749 S.Diag(IndirectJumps[0]->getBeginLoc(), in VerifyIndirectJumps()
750 diag::err_indirect_goto_without_addrlabel); in VerifyIndirectJumps()
777 if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(TheLabel->getStmt()))) in VerifyIndirectJumps()
779 unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()]; in VerifyIndirectJumps()
817 // we've marked reachable. For well-formed code this amortizes in VerifyIndirectJumps()
819 // when we see something unmarked, and in well-formed code we in VerifyIndirectJumps()
832 // Don't walk out if we've reached the top-level scope or we've in VerifyIndirectJumps()
836 // Don't walk out through an out-diagnostic. in VerifyIndirectJumps()
853 return (JumpDiag == diag::err_goto_into_protected_scope && in IsMicrosoftJumpWarning()
854 (InDiagNote == diag::note_protected_by_variable_init || in IsMicrosoftJumpWarning()
855 InDiagNote == diag::note_protected_by_variable_nontriv_destructor)); in IsMicrosoftJumpWarning()
862 InDiagNote == diag::note_protected_by_variable_non_pod; in IsCXX98CompatWarning()
871 S.Diag(Jump->getBeginLoc(), diag::err_indirect_goto_in_protected_scope) in DiagnoseIndirectOrAsmJumpStmt()
873 S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target) in DiagnoseIndirectOrAsmJumpStmt()
884 S.Diag(Scopes[ToScopes[I]].Loc, Scopes[ToScopes[I]].InDiag); in NoteJumpIntoScopes()
901 S.Diag(Scopes[I].Loc, Scopes[I].OutDiag); in DiagnoseIndirectOrAsmJump()
912 S.Diag(Scopes[I].Loc, Scopes[I].InDiag); in DiagnoseIndirectOrAsmJump()
915 // Diagnose this jump if it would be ill-formed in C++98. in DiagnoseIndirectOrAsmJump()
918 S.Diag(Jump->getBeginLoc(), in DiagnoseIndirectOrAsmJump()
919 diag::warn_cxx98_compat_indirect_goto_in_protected_scope) in DiagnoseIndirectOrAsmJump()
921 S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target) in DiagnoseIndirectOrAsmJump()
927 /// CheckJump - Validate that the specified jump statement is valid: that it is
948 if (Scopes[I].InDiag == diag::note_protected_by_seh_finally) { in CheckJump()
949 S.Diag(From->getBeginLoc(), diag::warn_jump_out_of_seh_finally); in CheckJump()
952 diag::note_omp_protected_structured_block) { in CheckJump()
953 S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope); in CheckJump()
954 S.Diag(To->getBeginLoc(), diag::note_omp_exits_structured_block); in CheckJump()
957 diag::note_acc_branch_into_compute_construct) { in CheckJump()
958 S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope); in CheckJump()
959 S.Diag(Scopes[I].Loc, diag::note_acc_branch_out_of_compute_construct); in CheckJump()
986 S.Diag(DiagLoc, JumpDiagWarning); in CheckJump()
990 Label->setSideEntry(true); in CheckJump()
995 S.Diag(DiagLoc, JumpDiagError); in CheckJump()
999 // Handle -Wc++98-compat warnings if the jump is well-formed. in CheckJump()
1001 S.Diag(DiagLoc, JumpDiagCXX98Compat); in CheckJump()
1007 if (GS->getLabel()->isMSAsmLabel()) { in CheckGotoStmt()
1008 S.Diag(GS->getGotoLoc(), diag::err_goto_ms_asm_label) in CheckGotoStmt()
1009 << GS->getLabel()->getIdentifier(); in CheckGotoStmt()
1010 S.Diag(GS->getLabel()->getLocation(), diag::note_goto_ms_asm_label) in CheckGotoStmt()
1011 << GS->getLabel()->getIdentifier(); in CheckGotoStmt()
1019 S.Diag(AS->getBeginLoc(), diag::err_musttail_scope); in VerifyMustTailStmts()
1020 S.Diag(Scopes[I].Loc, Scopes[I].OutDiag); in VerifyMustTailStmts()
1027 ArrayRef<const Attr *> Attrs = AS->getAttrs(); in GetMustTailAttr()