This is an archive of the discontinued LLVM Phabricator instance.

[clang][dataflow] Fix handling of base-class fields
ClosedPublic

Authored by ymandel on Mar 22 2022, 5:03 PM.

Details

Summary

This patch adds support for tracking of non-private base-class fields in derived classes.

Diff Detail

Event Timeline

ymandel created this revision.Mar 22 2022, 5:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2022, 5:03 PM
ymandel updated this revision to Diff 417906.Mar 24 2022, 6:24 AM

Added repros for equality-related failures.

ymandel retitled this revision from [clang][dataflow] Fields bug repro. NOT FOR REVIEW. to [clang][dataflow] Fix handling of base-class fields.Mar 31 2022, 6:46 AM
ymandel edited the summary of this revision. (Show Details)
ymandel updated this revision to Diff 419440.Mar 31 2022, 7:00 AM
ymandel edited the summary of this revision. (Show Details)

added missing call

ymandel published this revision for review.Mar 31 2022, 7:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 31 2022, 7:25 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
sgatev accepted this revision.Mar 31 2022, 7:50 AM
sgatev added inline comments.
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
168

Let's add to the documentation of AggregateStorageLocation and StructValue that they implement a flat struct layout. I don't see an immediate reason to revisit this, but let's be explicit about it.

182

The clang namespace is unnecessary.

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
1014

Add a similar test with class instead of struct?

1015

Let's also add private and protected members in A and a private member in B.

This revision is now accepted and ready to land.Mar 31 2022, 7:50 AM
xazax.hun added inline comments.Mar 31 2022, 8:20 AM
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
185

Will this work well for all cases of diamond shape inheritance?

E.g.:

struct A { int a; };
struct B : virtual A { int b; };
struct C : virtual A { int c; };
struct D : B, C { int d; };

In the above code, I would expect the field a to appear only once. I guess this should work well because of the set representation although we will visit A twice.

On the other hand, consider:

struct A { int a; };
struct B : A { int b; };
struct C : A { int c; };
struct D : B, C { int d; };

Here, in fact, we have 2 instances of the field a. Both B::a and C::a are part of D. I suspect that the current implementation might not handle this.

ymandel updated this revision to Diff 419496.Mar 31 2022, 9:25 AM

address reviewer comments

ymandel updated this revision to Diff 419499.Mar 31 2022, 9:31 AM
ymandel marked 5 inline comments as done.

adjusted test

Thanks for the reviews.

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
185

Good point, no. But, I'm not sure that fixing this here would be enough - I think we'd also need to revisit how we model structs, since getChild takes a decl as argument -- it doesn't support multiple versions of the same field decl.

I added a FIXME since this seems a larger issue, but let me know if you think it needs fixing now.

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
1014

I went with a simpler test for struct, only verifying that the default is understood correctly (and differently than class), but happy to expand it.

xazax.hun accepted this revision.Mar 31 2022, 9:36 AM
xazax.hun added inline comments.
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
185

I think the argument of getChild needs fixing as well is strong enough to push this to a separate PR.

ymandel added a subscriber: kinu.Mar 31 2022, 10:58 AM
sgatev accepted this revision.Mar 31 2022, 10:42 PM
sgatev added inline comments.
clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
59–60 ↗(On Diff #419499)

I find this a bit confusing. StructValue does not contain storage locations in general. I think we should make it clear that the layout of AggregateStorageLocation is flat, i.e. if it's used for a struct or class type it will contain child storage locations for all accessible members of base struct and class types.

clang/include/clang/Analysis/FlowSensitive/Value.h
193–194 ↗(On Diff #419499)

I'm not sure what's meant here by indirect reachability, but I suggest documenting that a StructValue that models a struct or class type contains child values for all accessible members of its base struct and class types.

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
1097–1100
1102–1111

Let's also check FooLoc's child storage locations. Same for the test below.

1156–1159
ymandel updated this revision to Diff 419743.Apr 1 2022, 6:43 AM

address comments

ymandel updated this revision to Diff 419744.Apr 1 2022, 6:48 AM
ymandel marked 5 inline comments as done.

add clarifying comment

clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
59–60 ↗(On Diff #419499)

Updated. I misunderstood what you meant as "flat" in the previous round of comments. Thanks for clarifying!

ymandel updated this revision to Diff 419751.Apr 1 2022, 7:17 AM

tweak comment

This revision was landed with ongoing or failed builds.Apr 1 2022, 8:02 AM
This revision was automatically updated to reflect the committed changes.