diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-12-15 18:44:22 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-12-15 18:44:22 +0000 |
commit | 0827408865e32789e0ec4b8113a302ccdc531423 (patch) | |
tree | d8c9122a107aab93c08b01adb6df4f9c954c3705 /lib/Lex | |
parent | c46333550f5787b6d48ca3043e14ba9594cb632d (diff) |
Fix diagnostic pragmas.
Diagnostic pragmas are broken because we don't keep track of the diagnostic state changes and we only check the current/latest state.
Problems manifest if a diagnostic is emitted for a source line that has different diagnostic state than the current state; this can affect
a lot of places, like C++ inline methods, template instantiations, the lexer, etc.
Fix the issue by having the Diagnostic object keep track of the source location of the pragmas so that it is able to know what is the diagnostic state at any given source location.
Fixes rdar://8365684.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 3 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 20 | ||||
-rw-r--r-- | lib/Lex/PPExpressions.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPLexerChange.cpp | 14 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 10 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 13 |
6 files changed, 40 insertions, 22 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index c6d09349b5..c819011338 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -22,8 +22,9 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) { IsBuiltinMacro = false; IsFromAST = false; IsDisabled = false; - IsUsed = true; + IsUsed = false; IsAllowRedefinitionsWithoutWarning = false; + IsWarnIfUnused = false; ArgumentList = 0; NumArguments = 0; diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 3414c27bfc..467d485888 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -1504,11 +1504,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { } } - // If this is the primary source file, remember that this macro hasn't been - // used yet. - if (isInPrimaryFile()) - MI->setIsUsed(false); - MI->setDefinitionEndLoc(LastTok.getLocation()); // Finally, if this identifier already had a macro defined for it, verify that @@ -1536,6 +1531,16 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { setMacroInfo(MacroNameTok.getIdentifierInfo(), MI); + assert(!MI->isUsed()); + // If we need warning for not using the macro, add its location in the + // warn-because-unused-macro set. If it gets used it will be removed from set. + if (isInPrimaryFile() && // don't warn for include'd macros. + Diags->getDiagnosticLevel(diag::pp_macro_not_used, + MI->getDefinitionLoc()) != Diagnostic::Ignored) { + MI->setIsWarnIfUnused(true); + WarnUnusedMacroLocs.insert(MI->getDefinitionLoc()); + } + // If the callbacks want to know, tell them about the macro definition. if (Callbacks) Callbacks->MacroDefined(MacroNameTok, MI); @@ -1569,6 +1574,9 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { if (Callbacks) Callbacks->MacroUndefined(MacroNameTok, MI); + if (MI->isWarnIfUnused()) + WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); + // Free macro definition. ReleaseMacroInfo(MI); setMacroInfo(MacroNameTok.getIdentifierInfo(), 0); @@ -1621,7 +1629,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef, // If there is a macro, process it. if (MI) // Mark it used. - MI->setIsUsed(true); + markMacroAsUsed(MI); // Should we include the stuff contained by this directive? if (!MI == isIfndef) { diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp index 79ed8677da..1451c5a1ef 100644 --- a/lib/Lex/PPExpressions.cpp +++ b/lib/Lex/PPExpressions.cpp @@ -112,7 +112,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) { MacroInfo *Macro = PP.getMacroInfo(II); - Macro->setIsUsed(true); + PP.markMacroAsUsed(Macro); } // Consume identifier. diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 4a40405992..eef42b69d8 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -250,15 +250,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { CurPPLexer = 0; - // This is the end of the top-level file. If the diag::pp_macro_not_used - // diagnostic is enabled, look for macros that have not been used. - if (getDiagnostics().getDiagnosticLevel(diag::pp_macro_not_used) != - Diagnostic::Ignored) { - for (macro_iterator I = macro_begin(false), E = macro_end(false); - I != E; ++I) - if (!I->second->isUsed()) - Diag(I->second->getDefinitionLoc(), diag::pp_macro_not_used); - } + // This is the end of the top-level file. 'WarnUnusedMacroLocs' has collected + // all macro locations that we need to warn because they are not used. + for (WarnUnusedMacroLocsTy::iterator + I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end(); I!=E; ++I) + Diag(*I, diag::pp_macro_not_used); return true; } diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index d3f3db31da..333da11143 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -223,7 +223,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } // Notice that this macro has been used. - MI->setIsUsed(true); + markMacroAsUsed(MI); // If we started lexing a macro, enter the macro expansion body. @@ -869,3 +869,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { } CreateString(OS.str().data(), OS.str().size(), Tok, Tok.getLocation()); } + +void Preprocessor::markMacroAsUsed(MacroInfo *MI) { + // If the 'used' status changed, and the macro requires 'unused' warning, + // remove its SourceLocation from the warn-for-unused-macro locations. + if (MI->isWarnIfUnused() && !MI->isUsed()) + WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); + MI->setIsUsed(true); +} diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 58625520a9..e6a53a1043 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -646,7 +646,11 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { if (iter != PragmaPushMacroInfo.end()) { // Release the MacroInfo currently associated with IdentInfo. MacroInfo *CurrentMI = getMacroInfo(IdentInfo); - if (CurrentMI) ReleaseMacroInfo(CurrentMI); + if (CurrentMI) { + if (CurrentMI->isWarnIfUnused()) + WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc()); + ReleaseMacroInfo(CurrentMI); + } // Get the MacroInfo we want to reinstall. MacroInfo *MacroToReInstall = iter->second.back(); @@ -810,6 +814,7 @@ public: explicit PragmaDiagnosticHandler() : PragmaHandler("diagnostic") {} virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &DiagToken) { + SourceLocation DiagLoc = DiagToken.getLocation(); Token Tok; PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::identifier)) { @@ -828,12 +833,12 @@ public: else if (II->isStr("fatal")) Map = diag::MAP_FATAL; else if (II->isStr("pop")) { - if (!PP.getDiagnostics().popMappings()) + if (!PP.getDiagnostics().popMappings(DiagLoc)) PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop); return; } else if (II->isStr("push")) { - PP.getDiagnostics().pushMappings(); + PP.getDiagnostics().pushMappings(DiagLoc); return; } else { PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); @@ -883,7 +888,7 @@ public: } if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.c_str()+2, - Map)) + Map, DiagLoc)) PP.Diag(StrToks[0].getLocation(), diag::warn_pragma_diagnostic_unknown_warning) << WarningName; } |