[PATCH] D159248: Fix crash when struct with inheritance is initialized with InitExpr

Kinuko Yasuda via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 30 23:38:00 PDT 2023


kinu created this revision.
Herald added a reviewer: NoQ.
Herald added a project: All.
kinu requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This fix still leaves inherited fields from base classes unpopulated
(even if they are accessed in the code), and might cause false
positives, but fix crashes that could happen because of source /
destination mismatches.

More details:
When a struct is declared, the Record value of the struct is usually
initialized with `Environment::createValue()` which internally calls
`getObjectFields()` (via filtering in `DACtx::getModeledFields()`)
to collects all fields from the current and base classes.

However, if a struct is initialized with InitListExpr, its fields are
initialized based on what is returned by `getFieldsForInitListExpr()`,
which doesn't collect fields from base classes. Moreover, if the base
classes have their own InitListExpr, those InitListExpr's are also
visited, but the field values and locations that are initialized by
them are not merged when the child class's InitListExpr is visited.

This doesn't usually result in a crash, except for the cases where the
struct is used to construct a new struct of the same type with copy/move
constructor: in such a case the destination struct is
created with a regular `createValue()`, and therefore also have
fields from the base classes, but the source struct does not.
And when `copyRecord()` tries to copy the fields by looping over
the destination fields, it crashes because the source struct may
not have the fields.

This change adds a new `getChildOrError()` method in `StorageLocation`
and uses it in `copyRecord()`, so that only the fields that exist in
both record can be copied.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159248

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/lib/Analysis/FlowSensitive/RecordOps.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159248.554905.patch
Type: text/x-patch
Size: 5231 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230831/3d317753/attachment-0001.bin>


More information about the cfe-commits mailing list