This is an archive of the discontinued LLVM Phabricator instance.

[dataflow] HTMLLogger - show the value of the current expr
ClosedPublic

Authored by sammccall on Apr 21 2023, 12:03 PM.

Diff Detail

Event Timeline

sammccall created this revision.Apr 21 2023, 12:03 PM
Herald added a project: Restricted Project. · View Herald Transcript
sammccall requested review of this revision.Apr 21 2023, 12:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 21 2023, 12:03 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
sammccall edited the summary of this revision. (Show Details)Apr 21 2023, 12:05 PM
sammccall added reviewers: gribozavr2, mboehme.
mboehme added inline comments.Apr 24 2023, 2:53 AM
clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
96

IIUC, this places properties on the current HTML element as attributes, just like the built-in attributes that we add for other purposes (e.g. "value_id", "kind").

  • What happens if we have a property whose name conflicts with one of the built-in attributes?
  • Even if we don't have a naming conflict, I think it could be potentially confusing to have user-defined properties appear in the same list and in the same way as built-in attributes.

Suggestion: Can we nest all properties inside of a "properties" attribute?

Edit: Having looked at the HTML template now, I see that we exclude certain attributes there ('kind', 'value_id', 'type', 'location') when listing properties. I still think naming conflicts are a potential problem though. I think it would also be clearer to explicitly pick the properties out of a properties attribute rather than excluding a blocklist of attributes.

121–123
122

Same rationale as for properties above: can we nest the fields inside of a fields attribute?

I think it would also be useful to distinguish between properties and fields in the HTML output; probably not with another nesting level (yikes!), but just rendered differently. This could easily be done if they were separated into properties and fields attributes.

149
clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
179

Can you add some additional tests for the following?

  • Pointers
  • References
  • Properties
  • Struct fields

Ideally, other value kinds too (see copy-paste error above for BiconditionalValue).

sammccall marked an inline comment as done.Apr 24 2023, 6:53 AM
sammccall added inline comments.
clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
96

Right, the data model is: a value (really, a Value/StorageLocation mashed together) is just a bag of attributes.

I don't think making it more complicated is an improvement: being built-in isn't the same thing as being custom-rendered.
e.g. "pointee" and "truth" want the default key-value rendering despite being built-in.
Having the exclude list in the template is ugly, but either you end up encoding the rendering info twice in the template like that, or you encode it once in the template and once in the JSON generation (by what goes in the "properties" map vs the main map). I'd rather call this purely a template concern.

Namespace conflict could be a problem: the current behavior is that the last value wins (per JS rules).
IMO the simplest fix is to prepend "p:" and "f:" to properties/struct fields. These would be shown - otherwise the user can't distinguish between a property & field with the same name.

I had this in the prototype, but dropped them because they seemed a bit ugly and conflicts unlikely in practice. WDYT?

121–123

this is neat but capturing the structured binding Val is a C++20 feature

149

right, thanks :-(
Can't wait to get rid of this stuff :-)

clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp
179

There isn't a reasonable way to test in that level of detail without paying a lot for it.
String assertions on the HTML are not suitable for testing nontrivial structures in the JSON.

If we restructure to allow such assertions on the JSON:

  • it would be significantly expensive/intrusive
  • we would be relying on details of the analysis itself and setting them up indirectly - quite brittle
  • we would spend a lot on testing and still not look at all at what matters (the rendering)

My experience is that not having proper tests for these kind of tools is the least-worst option: better than brittle tests where true vs spurious errors are unclear, and better than expensive+still incomplete tests.
The debugging tools tend to get changed infrequently, manually verified, and sometimes an annoying regression creeps in.

sammccall updated this revision to Diff 516392.Apr 24 2023, 6:53 AM
sammccall marked an inline comment as done.

fix bad cast

sammccall updated this revision to Diff 516395.Apr 24 2023, 6:59 AM

use p: and f: prefixes for properties/fields respectively

(we can remove these again if too annoying)

mboehme added inline comments.Apr 25 2023, 12:25 AM
clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
96

Namespace conflict could be a problem: the current behavior is that the last value wins (per JS rules).
IMO the simplest fix is to prepend "p:" and "f:" to properties/struct fields. These would be shown - otherwise the user can't distinguish between a property & field with the same name.

Yes, this makes sense to me. I looked at your example screenshot and wasn't sure whether they were both fields or whether one of them was a property -- I think there's value in indicating explicitly what they are.

I had this in the prototype, but dropped them because they seemed a bit ugly and conflicts unlikely in practice. WDYT?

I do think there's a fair chance of conflicts -- many of the attribute names here are short and generic and look like likely field names (e.g. kind, type). Even if the chance of a conflict is relatively low, a conflict will be pretty confusing when it does happen -- and given that we'll be using this feature when we're debugging (i.e. already confused), I think this is worth avoiding.

One more question: How do the "p:" and "f:" items sort in the output? I think these should be sorted together and grouped -- e.g. builtins first, then fields, then properties. (Yes, I know this is more work... but I think it's worth it.)

121–123

Are you sure? I can see nothing here that would indicate this:

https://en.cppreference.com/w/cpp/language/structured_binding

And Clang doesn't complain in -std=c++17:

https://godbolt.org/z/jvYE3cTdq

display properties at the end of the kv list

clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
96

One more question: How do the "p:" and "f:" items sort in the output? I think these should be sorted together and grouped -- e.g. builtins first, then fields, then properties. (Yes, I know this is more work... but I think it's worth it.)

Javascript objects are ordered these days, so they'll display in the order we output them here.
So they're already grouped, I rearranged to put properties at the end.

121–123

Hmm, what about this :-)

Structured bindings cannot be captured by lambda expressions: (until C++20)

https://godbolt.org/z/jvYE3cTdq

The capture is the problem: https://godbolt.org/z/e5P43G754

mboehme added inline comments.Apr 26 2023, 2:38 AM
clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
96

One more question: How do the "p:" and "f:" items sort in the output? I think these should be sorted together and grouped -- e.g. builtins first, then fields, then properties. (Yes, I know this is more work... but I think it's worth it.)

Javascript objects are ordered these days, so they'll display in the order we output them here.

Got it, thanks.

So they're already grouped, I rearranged to put properties at the end.

SG

121–123

Ah, thanks -- that's the bit I didn't understand.

mboehme accepted this revision.Apr 26 2023, 2:38 AM
This revision is now accepted and ready to land.Apr 26 2023, 2:38 AM
This revision was landed with ongoing or failed builds.Apr 26 2023, 8:15 AM
This revision was automatically updated to reflect the committed changes.