On Nov 10, 2010, at 10:55 PM, Chris Lattner wrote:

> 
> On Nov 10, 2010, at 7: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.
>> 
>> 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
> 
> Are these timings with assertions disabled?  0.6% isn't a showstopper, but it 
> is unfortunate.

Yep, assertions disabled.

> 
> 
> A couple random thoughts:
> 
> +  struct DiagStatePoint {
> +    DiagState *State;
> +    FullSourceLoc Loc;
> 
> This shouldn't have to store a FullSourceLoc in the vector, it can just store 
> a SourceLocation and store the SourceMgr outside the vector.  Likewise, 
> GetDiagStatePointForLoc, getDiagnosticLevel etc can just take a 
> SourceLocation.  Since we're storing more per-translation unit stuff in the 
> diagnostics object, we should really just give up and give Diagnostics a 
> SourceManager& that is initialized at construction time.

I originally tried to do that but it wasn't appropriate due to the Diagnostic 
object being generally created ahead of everything else. But...

> 
> A more general concern I have about this change (pointed out by this) is that 
> you're adding translation unit state to the Diagnostic object.  I guess we 
> already had that due to mutation before so this isn't any worse, it just 
> seems weird to me :)

That is a good point! How about moving that stuff out into a new 
DiagnosticState object that is owned by Preprocessor and gets passed to 
Diagnostic which will have no translation unit state anymore ?
DiagnosticState will have a SourceManager& and accept SourceLocations, not 
FullSourceLocs.

> 
> +  bool isBeforeThan(SourceLocation Loc) const;
> +  bool isBeforeThan(const FullSourceLoc &Loc) const {
> 
> The name 'isBeforeThan' doesn't make a lot of sense to me.  Also, please add 
> a doxygen comment.  Why does this method pass FullSourceLoc by const& when 
> the others pass by value?

This won't be necessary with the above suggestion.

-Argiris

> 
> Otherwise, looks great, thanks for working on this!!
> 
> -Chris
> _______________________________________________
> 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