<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Dec 13, 2017, at 12:46 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Dec 13, 2017, at 3:22 PM, Saleem Abdulrasool &lt;<a href="mailto:compnerd@compnerd.org" class="">compnerd@compnerd.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 13, 2017, at 12:14 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="Apple-interchange-newline">On Dec 13, 2017, at 2:56 PM, Saleem Abdulrasool &lt;<a href="mailto:compnerd@compnerd.org" class="">compnerd@compnerd.org</a>&gt; wrote:<br class=""><br class="">Hey guys,<br class=""><br class="">I have another fun case that things go wrong in :-). &nbsp;We do not preserve the calling convention information when importing function decls via the ClangImporter. &nbsp;I have a pretty simple example in apple/swift#13404. &nbsp;Importing the following:<br class=""><br class=""><blockquote type="cite" class="">float frand(void);<br class="">float fadd(float f, float g) { return f + g; }<br class=""></blockquote><br class="">and using this in swift as:<br class=""><br class=""><blockquote type="cite" class="">func f -&gt; Float { return fadd(frand(), frand()); }<br class=""></blockquote><br class=""><br class="">will result in the fadd call being elided due to the UB in the CC mismatch. &nbsp;Im pretty sure that we should be preserving CC information when importing the interface, probably in `VisitFunctionDecl` in ImportDecl.cpp (although, I believe it can also be lazily computed). &nbsp;Im not sure which really would be the best thing to do here.<br class=""><br class="">This can show up on other targets when interfaces uses `__attribute__((__pcs__))` or `__attribute__((__fastcall__))`, `__attribute__((__vectorcall__))`, `__attribute__((__regparm__([1-3])))`, `__attribute__((__stdcall__))`, `__attribute__((__thiscall__))`.<br class=""></blockquote><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">Without enhancing SIL, I'm not sure we have a good option besides refusing to import function declarations with non-standard CCs.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">I don't think we really want to change AST function types to handle arbitrary imported calling conventions, but we could change SILFunctionType to be able to store a Clang CC. However, this will require a little bit of extra work in that, if someone tries to pass around the address of a fastcall function as a @convention(c) function, we will have to introduce a thunk. &nbsp;I believe we already do similar kinds of thunking in SILGen, though.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"></div></blockquote><div class=""><br class=""></div><div class="">This is slightly problematic as Linux ARM HF and Windows ARM both use a non-C default (arm_aapcs_vfpcc) which is the test case in the mentioned PR. &nbsp;That is, even without the attributes the declarations above have a non-C CC.</div><div class=""><br class=""></div><div class="">I don't think that we are supporting arbitrary calling conventions per se. &nbsp;This only becomes a problem at the FFI layer, where we want to convert the swift CC to the foreign CC. &nbsp;The IRGen at that point will generate UB which will truncate the implementation when the LLVM optimizer runs. &nbsp;I think that we should at least support AAPCS in both, the standard and VFP, variants at the very least.</div></div></div></div></blockquote><div class=""><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Supporting two C calling conventions is not easier than supporting arbitrary C calling conventions. &nbsp;All the complexity is in how and where we represent those CCs. &nbsp;I'm hesitant to introduce this complexity (and non-portability) into the core language, which is why I'm suggesting just introducing it into SIL. &nbsp;But I explicitly do not want us to hard-code specific non-standard conventions from C outside of maybe attribute parsing; we should generalize the representation to support arbitrary CCs. &nbsp;I don't think this is hard at the SIL level.</span></div></blockquote><div><br class=""></div><div>Hmm, I think that we might be looking at different problems. &nbsp;I want to support the de facto standard CC on the target. &nbsp;If you consider Windows ARM, ā€œcā€ is entirely invalid. &nbsp;The equivalent of ā€œcā€ is arm_aapcs_vfpcc. &nbsp;However, there are other cases where we do need a secondary CC. &nbsp;As an example of that, the AEABI RT function calls are always made as AAPCS, but on Linux ARM HF targets (e.g. armv7-unknown-linux-gnueabihf), the default CC is the VFP variant of AAPCS, so we do need a secondary CC there for some library calls. &nbsp;We usually get lucky as the function calls there are formed by the backend which knows the CC necessary for the call there.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">In general, the importer has a lot of flexibility when importing declarations and very little flexibility when importing types, especially pointer types. &nbsp;We can only import one kind of function pointer type as a @convention(c) function type; everything else needs to be imported as an opaque pointer unless we actually bite the bullet and enhance the AST @convention system to support more C conventions. &nbsp;For maximum expressivity, that function pointer type needs to be the type most commonly used for function pointers on the platform, assuming there is one. &nbsp;It doesn't really matter if that's not the default calling convention for function *declarations* because we can always pass around a specific variant-CC function as a @convention(c) function value by introducing a thunk; function-pointer equality won't work, but probably nobody cares. &nbsp;What we can't do is turn an arbitrary variant-CC function *pointer* into a @convention(c) function pointer. &nbsp;But the correctness of all this relies on SIL being able to fully represent the C calling convention.</div></div></blockquote><div><br class=""></div><div>In the case of support of a target which does not support the C calling convention but expects all calls to be of a specific convention, we currently fall apart. &nbsp;It sounds like you would prefer that the approach to handle that would be to map `@convention(c)` to that alternate calling convention? &nbsp;For importing declarations, we currently do not preserve the calling convention at all. &nbsp;As a result, right now, FFI calls into C may introduce UB in the IR.</div><div><br class=""></div><div>I think that the FFI to declarations is far more common than the FFI to a function pointer, which is why I am focusing on the imported declaration rather than the imported types. &nbsp;I do agree that supporting additional conventions in the SIL layer would be good for the imported function pointer case. &nbsp;Am I missing something and is the `@convention` used for the imported declarations too?</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">John.</div></div></blockquote></div><br class=""></body></html>