This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Pass correct bldrCtx to computeObjectUnderConstruction
ClosedPublic

Authored by tomasz-kaminski-sonarsource on Aug 17 2022, 7:39 AM.

Details

Summary

In case when the prvalue is returned from the function (kind is one
of SimpleReturnedValueKind, CXX17ElidedCopyReturnedValueKind),
then it construction happens in context of the caller.
We pass BldrCtx explicitly, as currBldrCtx will always refer to callee
context.

In the following example:

struct Result {int value; };
Result create() { return Result{10}; }
int accessValue(Result r) { return r.value; }

void test() {
   for (int i = 0; i < 2; ++i)
      accessValue(create());
}

In case when the returned object was constructed directly into the
argument to a function call accessValue(create()), this led to
inappropriate value of blockCount being used to locate parameter region,
and as a consequence resulting object (from create()) was constructed
into a different region, that was later read by inlined invocation of
outer function (accessValue).
This manifests itself only in case when calling block is visited more
than once (loop in above example), as otherwise there is no difference
in blockCount value between callee and caller context.
This happens only in case when copy elision is disabled (before C++17).

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald Transcript

Fixed warrning checks and added newline.

This is now ready for review.

tomasz-kaminski-sonarsource published this revision for review.Aug 17 2022, 8:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2022, 8:42 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
NoQ added a comment.Aug 18 2022, 12:23 AM

Beautiful find, thanks!

clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
757–758

You probably want an updated builder context here as well. This function should be a simple wrapper, it should be completely interchangeable with calling both functions directly.

clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
757–758

Could you please elaborate more? I would see a reason to create a context here if I would expect that currBlrdCtx refers to a different Block that we want to perform construction in. And there is no indication on another Block being inplay here, and I would construct NodeBlockCtx with same block as currBldrCtx.
In other words, I expect this function to be handeConstructionContext in current Block.

clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
757–758

Or to say it differently, I expect BldCtx not being currBldrCtx to be an unusual situation, that is limited to the construction of return value. Thus having it in convenience would only make it more currbesome.

@NoQ Do you agree with my view on handleConstructionContext, if so is this patch ready to land?

NoQ added inline comments.Aug 26 2022, 10:11 AM
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
757–758

No-no, I mean, it's not any concrete bug that I see, it's maintaining API contracts to make the code easy to understand and make it harder to make mistakes in the future.

The function handleConstructionContext() , by design, is supposed to be equivalent to calling computeObjectUnderConstruction() and updateObjectsUnderConstruction(). Whenever someone has to perform both steps, they can combine them together with this convenience wrapper.

After your patch, they won't be able to combine the two calls in a situation when they need to pass a non-current builder context to computeObjectUnderConstruction(). I hope they'll be able to figure out that they need to add another parameter but I'm worried that they may think "oh this big function doesn't need that parameter, let's drop it". Because the bug you've found is quite subtle, it's easy to miss why we even need to pass that parameter.

So I suggest to add the new parameter to handleConstructionContext() as well, and pass it manually on all call sites.

  • Pass BldrCtx to handleConstructionContext
tomasz-kaminski-sonarsource marked an inline comment as done.Aug 29 2022, 12:34 AM
tomasz-kaminski-sonarsource added inline comments.
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
757–758

Change applied.

tomasz-kaminski-sonarsource marked an inline comment as done.Aug 29 2022, 12:35 AM
NoQ accepted this revision.Sep 20 2022, 5:35 PM

LGTM!

Thanks again for your investigation. And patience!

This revision is now accepted and ready to land.Sep 20 2022, 5:35 PM