@@ -93,7 +93,7 @@ class JumpScopeChecker {
9393 unsigned TargetScope);
9494 void CheckJump (Stmt *From, Stmt *To, SourceLocation DiagLoc,
9595 unsigned JumpDiag, unsigned JumpDiagWarning,
96- unsigned JumpDiagCXX98Compat );
96+ unsigned JumpDiagCompat );
9797 void CheckGotoStmt (GotoStmt *GS);
9898 const Attr *GetMustTailAttr (AttributedStmt *AS);
9999
@@ -179,9 +179,8 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {
179179 }
180180 }
181181
182- if (const Expr *Init = VD->getInit (); S.Context .getLangOpts ().CPlusPlus &&
183- VD->hasLocalStorage () && Init &&
184- !Init->containsErrors ()) {
182+ if (const Expr *Init = VD->getInit ();
183+ VD->hasLocalStorage () && Init && !Init->containsErrors ()) {
185184 // C++11 [stmt.dcl]p3:
186185 // A program that jumps from a point where a variable with automatic
187186 // storage duration is not in scope to a point where it is in scope
@@ -680,7 +679,9 @@ void JumpScopeChecker::VerifyJumps() {
680679 CheckJump (GS, GS->getLabel ()->getStmt (), GS->getGotoLoc (),
681680 diag::err_goto_into_protected_scope,
682681 diag::ext_goto_into_protected_scope,
683- diag::warn_cxx98_compat_goto_into_protected_scope);
682+ S.getLangOpts ().CPlusPlus
683+ ? diag::warn_cxx98_compat_goto_into_protected_scope
684+ : diag::warn_cpp_compat_goto_into_protected_scope);
684685 }
685686 CheckGotoStmt (GS);
686687 continue ;
@@ -708,7 +709,9 @@ void JumpScopeChecker::VerifyJumps() {
708709 CheckJump (IGS, Target->getStmt (), IGS->getGotoLoc (),
709710 diag::err_goto_into_protected_scope,
710711 diag::ext_goto_into_protected_scope,
711- diag::warn_cxx98_compat_goto_into_protected_scope);
712+ S.getLangOpts ().CPlusPlus
713+ ? diag::warn_cxx98_compat_goto_into_protected_scope
714+ : diag::warn_cpp_compat_goto_into_protected_scope);
712715 continue ;
713716 }
714717
@@ -725,7 +728,9 @@ void JumpScopeChecker::VerifyJumps() {
725728 else
726729 Loc = SC->getBeginLoc ();
727730 CheckJump (SS, SC, Loc, diag::err_switch_into_protected_scope, 0 ,
728- diag::warn_cxx98_compat_switch_into_protected_scope);
731+ S.getLangOpts ().CPlusPlus
732+ ? diag::warn_cxx98_compat_switch_into_protected_scope
733+ : diag::warn_cpp_compat_switch_into_protected_scope);
729734 }
730735 }
731736}
@@ -867,6 +872,13 @@ static bool IsCXX98CompatWarning(Sema &S, unsigned InDiagNote) {
867872 InDiagNote == diag::note_protected_by_variable_non_pod;
868873}
869874
875+ // / Returns true if a particular note should be a C++ compatibility warning in
876+ // / C mode with -Wc++-compat.
877+ static bool IsCppCompatWarning (Sema &S, unsigned InDiagNote) {
878+ return !S.getLangOpts ().CPlusPlus &&
879+ InDiagNote == diag::note_protected_by_variable_init;
880+ }
881+
870882// / Produce primary diagnostic for an indirect jump statement.
871883static void DiagnoseIndirectOrAsmJumpStmt (Sema &S, Stmt *Jump,
872884 LabelDecl *Target, bool &Diagnosed) {
@@ -906,34 +918,43 @@ void JumpScopeChecker::DiagnoseIndirectOrAsmJump(Stmt *Jump, unsigned JumpScope,
906918 S.Diag (Scopes[I].Loc , Scopes[I].OutDiag );
907919 }
908920
909- SmallVector<unsigned , 10 > ToScopesCXX98Compat;
921+ SmallVector<unsigned , 10 > ToScopesCXX98Compat, ToScopesCppCompat ;
910922
911923 // Now walk into the scopes containing the label whose address was taken.
912924 for (unsigned I = TargetScope; I != Common; I = Scopes[I].ParentScope )
913925 if (IsCXX98CompatWarning (S, Scopes[I].InDiag ))
914926 ToScopesCXX98Compat.push_back (I);
927+ else if (IsCppCompatWarning (S, Scopes[I].InDiag ))
928+ ToScopesCppCompat.push_back (I);
915929 else if (Scopes[I].InDiag ) {
916930 DiagnoseIndirectOrAsmJumpStmt (S, Jump, Target, Diagnosed);
917931 S.Diag (Scopes[I].Loc , Scopes[I].InDiag );
918932 }
919933
920- // Diagnose this jump if it would be ill-formed in C++98 .
921- if (!Diagnosed && !ToScopesCXX98Compat. empty () ) {
934+ // Diagnose this jump if it would be ill-formed in C++[98] .
935+ if (!Diagnosed) {
922936 bool IsAsmGoto = isa<GCCAsmStmt>(Jump);
923- S.Diag (Jump->getBeginLoc (),
924- diag::warn_cxx98_compat_indirect_goto_in_protected_scope)
925- << IsAsmGoto;
926- S.Diag (Target->getStmt ()->getIdentLoc (), diag::note_indirect_goto_target)
927- << IsAsmGoto;
928- NoteJumpIntoScopes (ToScopesCXX98Compat);
937+ auto Diag = [&](unsigned DiagId, const SmallVectorImpl<unsigned > &Notes) {
938+ S.Diag (Jump->getBeginLoc (), DiagId) << IsAsmGoto;
939+ S.Diag (Target->getStmt ()->getIdentLoc (), diag::note_indirect_goto_target)
940+ << IsAsmGoto;
941+ NoteJumpIntoScopes (Notes);
942+ };
943+ if (!ToScopesCXX98Compat.empty ())
944+ Diag (diag::warn_cxx98_compat_indirect_goto_in_protected_scope,
945+ ToScopesCXX98Compat);
946+ else if (!ToScopesCppCompat.empty ())
947+ Diag (diag::warn_cpp_compat_indirect_goto_in_protected_scope,
948+ ToScopesCppCompat);
929949 }
930950}
931951
932952// / CheckJump - Validate that the specified jump statement is valid: that it is
933953// / jumping within or out of its current scope, not into a deeper one.
934954void JumpScopeChecker::CheckJump (Stmt *From, Stmt *To, SourceLocation DiagLoc,
935- unsigned JumpDiagError, unsigned JumpDiagWarning,
936- unsigned JumpDiagCXX98Compat) {
955+ unsigned JumpDiagError,
956+ unsigned JumpDiagWarning,
957+ unsigned JumpDiagCompat) {
937958 if (CHECK_PERMISSIVE (!LabelAndGotoScopes.count (From)))
938959 return ;
939960 if (CHECK_PERMISSIVE (!LabelAndGotoScopes.count (To)))
@@ -973,15 +994,16 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
973994 if (CommonScope == ToScope) return ;
974995
975996 // Pull out (and reverse) any scopes we might need to diagnose skipping.
976- SmallVector<unsigned , 10 > ToScopesCXX98Compat ;
997+ SmallVector<unsigned , 10 > ToScopesCompat ;
977998 SmallVector<unsigned , 10 > ToScopesError;
978999 SmallVector<unsigned , 10 > ToScopesWarning;
9791000 for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope ) {
9801001 if (S.getLangOpts ().MSVCCompat && JumpDiagWarning != 0 &&
9811002 IsMicrosoftJumpWarning (JumpDiagError, Scopes[I].InDiag ))
9821003 ToScopesWarning.push_back (I);
983- else if (IsCXX98CompatWarning (S, Scopes[I].InDiag ))
984- ToScopesCXX98Compat.push_back (I);
1004+ else if (IsCXX98CompatWarning (S, Scopes[I].InDiag ) ||
1005+ IsCppCompatWarning (S, Scopes[I].InDiag ))
1006+ ToScopesCompat.push_back (I);
9851007 else if (Scopes[I].InDiag )
9861008 ToScopesError.push_back (I);
9871009 }
@@ -1001,10 +1023,10 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
10011023 NoteJumpIntoScopes (ToScopesError);
10021024 }
10031025
1004- // Handle -Wc++98-compat warnings if the jump is well-formed.
1005- if (ToScopesError.empty () && !ToScopesCXX98Compat .empty ()) {
1006- S.Diag (DiagLoc, JumpDiagCXX98Compat );
1007- NoteJumpIntoScopes (ToScopesCXX98Compat );
1026+ // Handle -Wc++98-compat or -Wc++-compat warnings if the jump is well-formed.
1027+ if (ToScopesError.empty () && !ToScopesCompat .empty ()) {
1028+ S.Diag (DiagLoc, JumpDiagCompat );
1029+ NoteJumpIntoScopes (ToScopesCompat );
10081030 }
10091031}
10101032
0 commit comments