[cfe-commits] r139595 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/JumpDiagnostics.cpp test/SemaCXX/MicrosoftExtensions.cpp
Douglas Gregor
dgregor at apple.com
Tue Sep 13 10:04:53 PDT 2011
On Sep 13, 2011, at 9:57 AM, Francois Pichet wrote:
> On Tue, Sep 13, 2011 at 11:33 AM, Douglas Gregor <dgregor at apple.com> wrote:
>>
>> On Sep 13, 2011, at 3:26 AM, Francois Pichet wrote:
>>
>>> Author: fpichet
>>> Date: Tue Sep 13 05:26:51 2011
>>> New Revision: 139595
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=139595&view=rev
>>> Log:
>>> In Microsoft mode, downgrade "goto into protected scope" from error to warning if we are jumping over a variable initialization via a goto.
>>>
>>> This fixes a few errors when parsing MFC code with clang.
>>>
>>> Modified:
>>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> cfe/trunk/lib/Sema/JumpDiagnostics.cpp
>>> cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
>>>
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=139595&r1=139594&r2=139595&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 13 05:26:51 2011
>>> @@ -2657,6 +2657,8 @@
>>> InGroup<UnusedLabel>, DefaultIgnore;
>>>
>>> def err_goto_into_protected_scope : Error<"goto into protected scope">;
>>> +def warn_goto_into_protected_scope : ExtWarn<"goto into protected scope">,
>>> + InGroup<Microsoft>;
>>> def err_switch_into_protected_scope : Error<
>>> "switch case is in protected scope">;
>>> def err_indirect_goto_without_addrlabel : Error<
>>>
>>> Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=139595&r1=139594&r2=139595&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
>>> +++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Tue Sep 13 05:26:51 2011
>>> @@ -76,8 +76,8 @@
>>> void VerifyIndirectJumps();
>>> void DiagnoseIndirectJump(IndirectGotoStmt *IG, unsigned IGScope,
>>> LabelDecl *Target, unsigned TargetScope);
>>> - void CheckJump(Stmt *From, Stmt *To,
>>> - SourceLocation DiagLoc, unsigned JumpDiag);
>>> + void CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
>>> + unsigned JumpDiag, unsigned JumpDiagWarning);
>>>
>>> unsigned GetDeepestCommonScope(unsigned A, unsigned B);
>>> };
>>> @@ -476,7 +476,8 @@
>>> // With a goto,
>>> if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
>>> CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(),
>>> - diag::err_goto_into_protected_scope);
>>> + diag::err_goto_into_protected_scope,
>>> + diag::warn_goto_into_protected_scope);
>>> continue;
>>> }
>>>
>>> @@ -484,7 +485,7 @@
>>> if (IndirectGotoStmt *IGS = dyn_cast<IndirectGotoStmt>(Jump)) {
>>> LabelDecl *Target = IGS->getConstantTarget();
>>> CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(),
>>> - diag::err_goto_into_protected_scope);
>>> + diag::err_goto_into_protected_scope, 0);
>>> continue;
>>> }
>>
>> Does this 0 need to be diag::warn_goto_into_protected_scope?
>
> IndirectGoto is a gcc extension not supported by MSVC.
But Clang still parses it even when in Microsoft mode, right? We need to deal with the superset of modes.
>>
>>> @@ -493,7 +494,7 @@
>>> SC = SC->getNextSwitchCase()) {
>>> assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
>>> CheckJump(SS, SC, SC->getLocStart(),
>>> - diag::err_switch_into_protected_scope);
>>> + diag::err_switch_into_protected_scope, 0);
>>> }
>>> }
>>> }
>>> @@ -660,10 +661,20 @@
>>> S.Diag(Scopes[I].Loc, Scopes[I].InDiag);
>>> }
>>>
>>> +/// Return true if a particular error+note combination must be downgraded
>>> +/// to a warning in Microsoft mode.
>>> +static bool IsMicrosoftJumpWarning(unsigned JumpDiag, unsigned InDiagNote)
>>> +{
>>> + return (JumpDiag == diag::err_goto_into_protected_scope &&
>>> + (InDiagNote == diag::note_protected_by_variable_init ||
>>> + InDiagNote == diag::note_protected_by_variable_nontriv_destructor));
>>> +}
>>> +
>>> +
>>> /// CheckJump - Validate that the specified jump statement is valid: that it is
>>> /// jumping within or out of its current scope, not into a deeper one.
>>> -void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To,
>>> - SourceLocation DiagLoc, unsigned JumpDiag) {
>>> +void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
>>> + unsigned JumpDiagError, unsigned JumpDiagWarning) {
>>> assert(LabelAndGotoScopes.count(From) && "Jump didn't get added to scopes?");
>>> unsigned FromScope = LabelAndGotoScopes[From];
>>>
>>> @@ -679,19 +690,30 @@
>>> if (CommonScope == ToScope) return;
>>>
>>> // Pull out (and reverse) any scopes we might need to diagnose skipping.
>>> - SmallVector<unsigned, 10> ToScopes;
>>> - for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope)
>>> - if (Scopes[I].InDiag)
>>> - ToScopes.push_back(I);
>>> -
>>> - // If the only scopes present are cleanup scopes, we're okay.
>>> - if (ToScopes.empty()) return;
>>> -
>>> - S.Diag(DiagLoc, JumpDiag);
>>> -
>>> - // Emit diagnostics for whatever is left in ToScopes.
>>> - for (unsigned i = 0, e = ToScopes.size(); i != e; ++i)
>>> - S.Diag(Scopes[ToScopes[i]].Loc, Scopes[ToScopes[i]].InDiag);
>>> + SmallVector<unsigned, 10> ToScopesError;
>>> + SmallVector<unsigned, 10> ToScopesWarning;
>>> + for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope) {
>>> + if (S.getLangOptions().Microsoft &&
>>> + IsMicrosoftJumpWarning(JumpDiagError, Scopes[I].InDiag))
>>> + ToScopesWarning.push_back(I);
>>> + else if (Scopes[I].InDiag)
>>> + ToScopesError.push_back(I);
>>> + }
>>> +
>>> + // Handle warnings.
>>> + if (!ToScopesWarning.empty()) {
>>> + S.Diag(DiagLoc, JumpDiagWarning);
>>> + for (unsigned i = 0, e = ToScopesWarning.size(); i != e; ++i)
>>> + S.Diag(Scopes[ToScopesWarning[i]].Loc, Scopes[ToScopesWarning[i]].InDiag);
>>> + }
>>> +
>>> + // Handle errors.
>>> + if (!ToScopesError.empty()) {
>>> + S.Diag(DiagLoc, JumpDiagError);
>>> + // Emit diagnostics note for whatever is left in ToScopesError.
>>> + for (unsigned i = 0, e = ToScopesError.size(); i != e; ++i)
>>> + S.Diag(Scopes[ToScopesError[i]].Loc, Scopes[ToScopesError[i]].InDiag);
>>> + }
>>> }
>>
>> This will mean that we get the warnings/errors in a different order (in Microsoft mode) than we get the errors in non-Microsoft mode. Could you tweak this so that the warning/error order is consistent?
>>
>
> Not sure I understand what you mean here. There is only 1 diag error
> possible here (associated with multiple notes) + 1 possible diag
> warning in Microsoft mode.
>
> The loop is to print the notes and they must be associated with either
> the error or the warning.
Ahhh, sorry. I got confused.
- Doug
More information about the cfe-commits
mailing list