@@ -93,7 +93,7 @@ class JumpScopeChecker {
93
93
unsigned TargetScope);
94
94
void CheckJump (Stmt *From, Stmt *To, SourceLocation DiagLoc,
95
95
unsigned JumpDiag, unsigned JumpDiagWarning,
96
- unsigned JumpDiagCXX98Compat );
96
+ unsigned JumpDiagCompat );
97
97
void CheckGotoStmt (GotoStmt *GS);
98
98
const Attr *GetMustTailAttr (AttributedStmt *AS);
99
99
@@ -179,9 +179,8 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {
179
179
}
180
180
}
181
181
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 ()) {
185
184
// C++11 [stmt.dcl]p3:
186
185
// A program that jumps from a point where a variable with automatic
187
186
// storage duration is not in scope to a point where it is in scope
@@ -680,7 +679,9 @@ void JumpScopeChecker::VerifyJumps() {
680
679
CheckJump (GS, GS->getLabel ()->getStmt (), GS->getGotoLoc (),
681
680
diag::err_goto_into_protected_scope,
682
681
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);
684
685
}
685
686
CheckGotoStmt (GS);
686
687
continue ;
@@ -708,7 +709,9 @@ void JumpScopeChecker::VerifyJumps() {
708
709
CheckJump (IGS, Target->getStmt (), IGS->getGotoLoc (),
709
710
diag::err_goto_into_protected_scope,
710
711
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);
712
715
continue ;
713
716
}
714
717
@@ -725,7 +728,9 @@ void JumpScopeChecker::VerifyJumps() {
725
728
else
726
729
Loc = SC->getBeginLoc ();
727
730
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);
729
734
}
730
735
}
731
736
}
@@ -867,6 +872,13 @@ static bool IsCXX98CompatWarning(Sema &S, unsigned InDiagNote) {
867
872
InDiagNote == diag::note_protected_by_variable_non_pod;
868
873
}
869
874
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
+
870
882
// / Produce primary diagnostic for an indirect jump statement.
871
883
static void DiagnoseIndirectOrAsmJumpStmt (Sema &S, Stmt *Jump,
872
884
LabelDecl *Target, bool &Diagnosed) {
@@ -906,34 +918,43 @@ void JumpScopeChecker::DiagnoseIndirectOrAsmJump(Stmt *Jump, unsigned JumpScope,
906
918
S.Diag (Scopes[I].Loc , Scopes[I].OutDiag );
907
919
}
908
920
909
- SmallVector<unsigned , 10 > ToScopesCXX98Compat;
921
+ SmallVector<unsigned , 10 > ToScopesCXX98Compat, ToScopesCppCompat ;
910
922
911
923
// Now walk into the scopes containing the label whose address was taken.
912
924
for (unsigned I = TargetScope; I != Common; I = Scopes[I].ParentScope )
913
925
if (IsCXX98CompatWarning (S, Scopes[I].InDiag ))
914
926
ToScopesCXX98Compat.push_back (I);
927
+ else if (IsCppCompatWarning (S, Scopes[I].InDiag ))
928
+ ToScopesCppCompat.push_back (I);
915
929
else if (Scopes[I].InDiag ) {
916
930
DiagnoseIndirectOrAsmJumpStmt (S, Jump, Target, Diagnosed);
917
931
S.Diag (Scopes[I].Loc , Scopes[I].InDiag );
918
932
}
919
933
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) {
922
936
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);
929
949
}
930
950
}
931
951
932
952
// / CheckJump - Validate that the specified jump statement is valid: that it is
933
953
// / jumping within or out of its current scope, not into a deeper one.
934
954
void 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) {
937
958
if (CHECK_PERMISSIVE (!LabelAndGotoScopes.count (From)))
938
959
return ;
939
960
if (CHECK_PERMISSIVE (!LabelAndGotoScopes.count (To)))
@@ -973,15 +994,16 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
973
994
if (CommonScope == ToScope) return ;
974
995
975
996
// Pull out (and reverse) any scopes we might need to diagnose skipping.
976
- SmallVector<unsigned , 10 > ToScopesCXX98Compat ;
997
+ SmallVector<unsigned , 10 > ToScopesCompat ;
977
998
SmallVector<unsigned , 10 > ToScopesError;
978
999
SmallVector<unsigned , 10 > ToScopesWarning;
979
1000
for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope ) {
980
1001
if (S.getLangOpts ().MSVCCompat && JumpDiagWarning != 0 &&
981
1002
IsMicrosoftJumpWarning (JumpDiagError, Scopes[I].InDiag ))
982
1003
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);
985
1007
else if (Scopes[I].InDiag )
986
1008
ToScopesError.push_back (I);
987
1009
}
@@ -1001,10 +1023,10 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
1001
1023
NoteJumpIntoScopes (ToScopesError);
1002
1024
}
1003
1025
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 );
1008
1030
}
1009
1031
}
1010
1032
0 commit comments