This is an archive of the discontinued LLVM Phabricator instance.

[opaque pointer types] Fix the CallInfo passed to EmitCall in some edge cases.
ClosedPublic

Authored by jyknight on Feb 3 2019, 1:18 PM.

Details

Summary

Currently, EmitCall emits a call instruction with a function type
derived from the pointee-type of the callee. This *should* be the same
as the type created from the CallInfo parameter, but in some cases an
incorrect CallInfo was being passed.

All of these fixes were discovered by the addition of the assert in
EmitCall which verifies that the passed-in CallInfo matches the
Callee's function type.

As far as I know, these issues caused no bugs at the moment, as the
correct types were ultimately being emitted. But, some would become
problematic when pointee types are removed.

List of fixes:

  • arrangeCXXConstructorCall was passing an incorrect value for the number of Required args, when calling an inheriting constructor where the inherited constructor is variadic. (The inheriting constructor doesn't actually get passed any of the user's args, but the code was calculating it as if it did).
  • arrangeFreeFunctionLikeCall was not including the count of the pass_object_size arguments in the count of required args.
  • OpenCL uses other address spaces for the "this" pointer. However, commonEmitCXXMemberOrOperatorCall was not annotating the address space on the "this" argument of the call.
  • Destructor calls were being created with EmitCXXMemberOrOperatorCall instead of EmitCXXDestructorCall in a few places. This was a problem because the calling convention sometimes has destructors returning "this" rather than void, and the latter function knows about that, and sets up the types properly (through calling arrangeCXXStructorDeclaration), while the former does not.
  • generateObjCGetterBody: the 'objc_getProperty' function returns type 'id', but was being called as if it returned the particular property's type. (That is of course the *dynamic* return type, and there's a downcast immediately after.)
  • OpenMP user-defined reduction functions (#pragma omp declare reduction) can be called with a subclass of the declared type. In such case, the call was being setup as if the function had been actually declared to take the subtype, rather than the base type.

Diff Detail

Repository
rC Clang

Event Timeline

jyknight created this revision.Feb 3 2019, 1:18 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 3 2019, 1:18 PM
Herald added a subscriber: Anastasia. · View Herald Transcript
dblaikie accepted this revision.Feb 4 2019, 1:06 PM

Seems reasonable to me - but if you like you can wait for Richard who might have a more nuanced understanding of the code. (but I'm OK signing off on this if you are & Richard can provide any extra feedback post-commit)

clang/lib/CodeGen/CGCall.cpp
3837 ↗(On Diff #184975)

This will be warned as unused in a release build.

Would this be hideous if it's just all one big assert?

assert((CallInfo.isVariadic && CallInfo.getArgStruct) || IRFuncTy == getTypes().GetFunctionType(CallInfo));

(I think that's accurate?)

This revision is now accepted and ready to land.Feb 4 2019, 1:06 PM
jyknight marked an inline comment as done.Feb 4 2019, 6:52 PM
jyknight added inline comments.
clang/lib/CodeGen/CGCall.cpp
3837 ↗(On Diff #184975)

Clearer IMO to just put #ifndef NDEBUG around the block, so I'll do that.

This revision was automatically updated to reflect the committed changes.