On Nov 10, 2010, at 10:06 PM, Douglas Gregor wrote:

> 
> On Nov 10, 2010, at 9:34 PM, Argyrios Kyrtzidis wrote:
> 
>> 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. For example:
>> 
>> struct S {
>> #pragma clang diagnostic push
>> #pragma clang diagnostic ignored "-Wtautological-compare"
>>      void m() { int b = b==b; }
>> #pragma clang diagnostic pop
>> };
>> 
>> the pragmas do not work for suppressing the warning in the above case.
>> 
>> The attached patch fixes 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.
> 
> This is really cool, Argiris!
> 
> @@ -365,33 +376,56 @@ void Diagnostic::ReportDelayed() {
>   DelayedDiagArg2.clear();
> }
> 
> +Diagnostic::DiagStatePointsTy::iterator
> +Diagnostic::GetDiagStatePointForLoc(FullSourceLoc Loc) const {
> +  assert(!DiagStatePoints.empty());
> +  assert(DiagStatePoints.front().Loc.isInvalid() &&
> +         "Should have created a DiagStatePoint for command-line");
> +
> +  if (Loc.isInvalid())
> +    return DiagStatePoints.begin();
> 
> I guess I was expecting that we would return the last DiagStatePoint for an 
> invalid location (so that we get the most recent state), rather than the 
> first.

Yes, that is more appropriate, I'll make some changes.

> 
> diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
> index 4a40405..51b6dae 100644
> --- a/lib/Lex/PPLexerChange.cpp
> +++ b/lib/Lex/PPLexerChange.cpp
> @@ -252,12 +252,14 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool 
> isEndOfMacro) {
> 
>   // 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);
> +  for (macro_iterator I = macro_begin(false), E = macro_end(false); 
> +       I != E; ++I) {
> +    if (I->second->isUsed())
> +      continue;
> +    FullSourceLoc DefLoc(I->second->getDefinitionLoc(), getSourceManager());
> +    if (getDiagnostics().getDiagnosticLevel(diag::pp_macro_not_used, DefLoc) 
> !=
> +        Diagnostic::Ignored)
> +      Diag(DefLoc, diag::pp_macro_not_used);
>   }
> 
> It's unfortunate this fixing this check means that we always have to iterate 
> over all of the macros. In particular, I wonder if this causes 
> deserialization of macros of a PCH file, which would be a performance killer. 
> Could you check?

That is badness.

How about this; Since we know at macro creation time whether it needs to be 
checked or not, keep that information (CheckUsed) in MacroInfo.
For de/serialization keep in PCH the set of macros that need checking 
(CheckUsed && !IsUsed) and only deserialize these macros.

This also improves a bit the current situation where we deserialize all macros 
if the diagnostic is enabled.

-Argiris

> 
>> I've also made measurements to see how this fix impacts performance. I 
>> basically measured how long it takes to do a -fsyntax-only over the 
>> llvm/clang codebase and the results were:
>> 
>> before the fix: 722.83 sec
>> after the fix: 727.24 sec
>> 
>> So avoiding the fix only provides a 0.6% gain.
> 
> 
> Other than the above, I didn't notice any other opportunities for 
> optimization here. I think we have to suck up the cost in the name of 
> correctness.
> 
>       - Doug
> _______________________________________________
> cfe-commits mailing list
> [email protected]
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to