This is an archive of the discontinued LLVM Phabricator instance.

[clang][Interp] Implement zero-init of record types
ClosedPublic

Authored by tbaeder on Jun 30 2023, 12:59 AM.

Details

Summary

Unify CXXTemporaryObjectExpr and CXXConstructExpr code and zero-initialize the object if requested.

Hints on how to test this properly without creating some weird intermediate object are welcome of course. :)

Diff Detail

Event Timeline

tbaeder created this revision.Jun 30 2023, 12:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 30 2023, 12:59 AM
tbaeder requested review of this revision.Jun 30 2023, 12:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 30 2023, 12:59 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
tbaeder added inline comments.Jun 30 2023, 1:40 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
1115

I briefly talked about this with @aaron.ballman on IRC. The current interpreter properly zero-initialized all the fields of a struct, but the un-does the initialization again (and initializes them to a APValue::Indeterminate in HandleConstructorCall::SkipToField().

aaron.ballman added inline comments.Jul 25 2023, 7:52 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
1240

It looks like you're not initializing base classes or padding bits: http://eel.is/c++draft/dcl.init#general-6.2 -- we could use test coverage for both of those cases (don't forget to also test bit-fields). You should also have a test for zero init of unions.

clang/lib/AST/Interp/Descriptor.cpp
281–289

This looks pretty dangerous -- is it safe to assume the type is a constant array, or should this be a dyn_cast and the spurious return is for the else branch?

clang/test/AST/Interp/records.cpp
931

Why is x.a outside of its lifetime?

939

I think we should have more test coverage. I mentioned a few above, but other things to test would be inner classes (and anonymous members), like:

struct S {
  struct {
    int x, y;
  } v;
  union {
    float a;
    int b;
  };
};

and member pointers (because those aren't simple pointers):

struct A {
  void func();
};
struct S {
  void (A::*ptr)();
};
tbaeder updated this revision to Diff 545131.Jul 28 2023, 6:26 AM
tbaeder marked 2 inline comments as done.
tbaeder added inline comments.
clang/lib/AST/Interp/ByteCodeExprGen.cpp
1240

Unions and bitfields are generally not supported yet, and I'm not sure what you mean by padding bits - they don't exist at this stage. In storage however, they are always zero since we memset that to 0.

clang/lib/AST/Interp/Descriptor.cpp
281–289

I only need an ArrayType anyway, so should be fine.

clang/test/AST/Interp/records.cpp
931

That was just a wrong diagnostic that has since been fixed.

tbaeder added inline comments.Jul 28 2023, 6:28 AM
clang/test/AST/Interp/records.cpp
939

member pointers are also not handled yet.

tbaeder updated this revision to Diff 545146.Jul 28 2023, 6:58 AM
aaron.ballman added inline comments.Jul 28 2023, 7:24 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
1240

Unions and bitfields are generally not supported yet,

Let's add the test coverage and mark failures with FIXME comments; otherwise we risk forgetting to add the test coverage later.

and I'm not sure what you mean by padding bits - they don't exist at this stage. In storage however, they are always zero since we memset that to 0.

So long as we're validating that they're properly set to zero; that's the important part.

tbaeder updated this revision to Diff 545367.Jul 29 2023, 6:41 AM
tbaeder marked an inline comment as done.
This revision is now accepted and ready to land.Jul 31 2023, 6:41 AM
This revision was landed with ongoing or failed builds.Sep 5 2023, 2:23 AM
This revision was automatically updated to reflect the committed changes.