This is an archive of the discontinued LLVM Phabricator instance.

[Static Analyzer] Structured bindings to data members
ClosedPublic

Authored by isuckatcs on Jun 13 2022, 7:49 AM.

Details

Summary

Handling structured bindings to data members are relatively straightforward, as everything is taken care of by handleConstructor.

All that's left to do is just reading the values from the specific region.

At the moment if the struct is not considered a small struct (for more information see RegionStoreManager::bindStruct()), a lazy
compound value is created insted of an actual copy, from which the static analyzer fails to read the field values if they are Undefined,
it reads Unknown instead.

Diff Detail

Event Timeline

isuckatcs created this revision.Jun 13 2022, 7:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2022, 7:49 AM
isuckatcs requested review of this revision.Jun 13 2022, 7:49 AM
isuckatcs retitled this revision from [Static Analyzer] Structured binding to data members to [Static Analyzer] Structured bindings to data members.

I am not sure in what maturity do we handle lambda captures, but if we do handle them then this https://reviews.llvm.org/D122768 should be of your and your mentor's interest.

NoQ added inline comments.Jun 15 2022, 11:33 PM
clang/test/Analysis/uninit-structured-binding-struct.cpp
69

Another thing we could try to test is whether i is known to be equal to 1:

clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}

(https://clang.llvm.org/docs/analyzer/developer-docs/DebugChecks.html#exprinspection-checks)

NoQ accepted this revision.Jun 15 2022, 11:36 PM

I think this patch is straightforward and good to go. It's nice to know that we already handle most of this stuff out of the box.

I am not sure in what maturity do we handle lambda captures, but if we do handle them then this https://reviews.llvm.org/D122768 should be of your and your mentor's interest.

Oh thanks, that's gonna be fun! Our handling of lambdas is more or less ok, it still has missing pieces but we can at least handle some cases.

This revision is now accepted and ready to land.Jun 15 2022, 11:36 PM
isuckatcs updated this revision to Diff 437548.Jun 16 2022, 8:02 AM

Addressed the comment about using clang_analyzer_eval()

isuckatcs marked an inline comment as done.Jun 16 2022, 8:02 AM
xazax.hun accepted this revision.Jun 16 2022, 8:14 AM

I think you might want to add some test cases with a non-pod class. Of course, we can do way less in those cases. But at least the tests would demonstrate that we do not crash on code like that.

Otherwise it looks good to me, nice work!

xazax.hun added inline comments.Jun 16 2022, 8:18 AM
clang/test/Analysis/uninit-structured-binding-struct.cpp
49

Maybe we could also test the following scenario:

i = 2;
clang_analyzer_eval(tst.a == 2);
isuckatcs updated this revision to Diff 437562.Jun 16 2022, 9:05 AM

Addressed comments

isuckatcs marked an inline comment as done.Jun 16 2022, 9:05 AM

I think we stall lack a non-POD testcase. Otherwise it is good to go :)

isuckatcs updated this revision to Diff 437834.Jun 17 2022, 2:55 AM
  • Updated existing testcases so clang_analyzer_eval() evalutes the arguments
  • Added testcases with non-POD types.
xazax.hun accepted this revision.Jun 17 2022, 9:39 AM

Thanks, I think this is now OK to commit.

This revision was landed with ongoing or failed builds.Jun 17 2022, 10:50 AM
This revision was automatically updated to reflect the committed changes.

I missed this commit because it was not tagged by "[analyzer]".
What is the community preference about tagging CSA commits?

I read https://en.cppreference.com/w/cpp/language/structured_binding carefully, and there are a number of interesting rules that might deserve their own test case, even if this isn't the patch where you solve that issue, or believe that the solution handles it without the need for special case handling.

Just to name a few, you seem to not have test cases for when the bindings are cv-qualified. If you declare structured bindings like this:

struct s {
  int a;
  int b;
};

void a(void) {
  s tst;

  auto [i, j](tst); // Syntax (3) according to cppreference

  int x = i; // expected-warning{{Assigned value is garbage or undefined}}
}

then the bindings are direct initialized, not copy initialized.

I'm not sure that the actual standard has anything that cppreference doesn't, but maybe we could give it a glance.

clang/test/Analysis/uninit-structured-binding-struct.cpp
11

In the long run, it might make your own life easier to create more talkative test function names, like testPODDecomp or smt like that.

NoQ added a comment.Jul 6 2022, 7:04 PM

I missed this commit because it was not tagged by "[analyzer]".
What is the community preference about tagging CSA commits?

I think [analyzer] is a good tag, no need to change anything. I also just set up my subscriptions by directories rather than by tags and I like how it works.