<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Dec 11, 2014 at 4:55 PM, Peter Collingbourne <span dir="ltr"><<a href="mailto:peter@pcc.me.uk" target="_blank">peter@pcc.me.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">================<br>
<br>
Comment at: lib/Sema/SemaChecking.cpp:187<br>
<br>
@@ +186,3 @@<br>
<br>
+  BuiltinCall->setType(CE->getType());<br>
<br>
+  BuiltinCall->getCallee()->setType(CE->getCallee()->getType());<br>
<br>
+  BuiltinCall->setValueKind(CE->getValueKind());<br>
<br>
----------------<br>
<br>
</span><span class="">rsmith wrote:<br>
<br>
> pcc wrote:<br>
<br>
> > rsmith wrote:<br>
<br>
> > > This can't be right: multiple calls to the builtin will share the same callee and will want different types here. Just remove this line?<br>
<br>
> > I found this to be necessary in cases where the function returns an lvalue; without it, I was getting assertion failures.<br>
<br>
> ><br>
<br>
> > I thought this might be an issue as well, until I looked at the AST representation of builtin calls:<br>
<br>
> ><br>
<br>
> > ```<br>
<br>
> > |     |-CallExpr 0x4310ae0 <col:3, col:42> 'int' lvalue<br>
<br>
> > |     | |-ImplicitCastExpr 0x4310ac8 <col:3> 'int &(*)(void)' <BuiltinFnToFnPtr><br>
<br>
> > |     | | `-DeclRefExpr 0x4310960 <col:3> '<builtin fn type>' Function 0x43108c0 '__builtin_call_with_static_chain' 'void ()'<br>
<br>
> > |     | |-CallExpr 0x4310a50 <col:36, col:38> 'int' lvalue<br>
<br>
> > |     | | `-ImplicitCastExpr 0x4310a38 <col:36> 'int &(*)(void)' <FunctionToPointerDecay><br>
<br>
> > |     | |   `-DeclRefExpr 0x43109e0 <col:36> 'int &(void)' lvalue Function 0x42ca430 'f' 'int &(void)'<br>
<br>
> > |     | `-ImplicitCastExpr 0x4310b18 <col:41> 'int &(*)(void)' <FunctionToPointerDecay><br>
<br>
> > |     |   `-DeclRefExpr 0x4310a78 <col:41> 'int &(void)' lvalue Function 0x42ca430 'f' 'int &(void)'<br>
<br>
> > ```<br>
<br>
> ><br>
<br>
> > So we are only overwriting the type of the `BuiltinFnToFnPtr` cast. This seems to be not too bad (except that the argument types are wrong; I should fix that, but it didn't seem to cause any issues).<br>
<br>
> That's still not correct. Practically, we could share the same `ImplicitCastExpr` between multiple calls to the builtin (through template instantiation, for instance), and theoretically, it's wrong to have a `BuiltinFnToFnPtr` cast that performs some conversion other than function-to-pointer decay. One reasonable thing to do here would be to create a new `ImplicitCastExpr` node to represent the conversion between function pointer types. (Another would be to teach whatever code was asserting that it shouldn't assume the call return type matches that of the callee for a call to a builtin -- I guess this is probably the ExprClassification.cpp code?)<br>
<br>
> Practically, we could share the same ImplicitCastExpr between multiple calls to the builtin (through template instantiation, for instance)<br><br>
</span>Fair point. I couldn't get this to trigger during template instantiation, but I suppose it could happen in other cases or if we change how template instantiation works.<br><span class=""><br>
> theoretically, it's wrong to have a BuiltinFnToFnPtr cast that performs some conversion other than function-to-pointer decay.<br>
<br>
<br>
<br>
</span>I don't understand why. We get to decide what the semantics of the various implicit casts are, and it seems reasonable to me for `BuiltinFnToFnPtr` to also represent the conversion of a generic builtin to a specific type. I also couldn't find any existing code that depends on `BuiltinFnToFnPtr` being a strict function-to-pointer decay conversion.</blockquote><div><br></div><div>Hmm, you're absolutely right, I was mixing this up with the more usual CK_FunctionToPointerDecay. I think it'd be fine to create a new ImplicitCastExpr with the right destination type here.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> One reasonable thing to do here would be to create a new ImplicitCastExpr node to represent the conversion between function pointer types.<br>
<br>
<br>
<br>
</span>Agreed that the code should create a new `ImplicitCastExpr` instead of trying to change the existing one, but I think you also meant that we should introduce a new cast kind for this case, which I don't think is necessary.</blockquote><div><br></div><div>I meant to use something like CK_BitCast, not to introduce a new cast kind. But you've convinced me that it's fine to use CK_BuiltinFnToFnPtr. =)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> Another would be to teach whatever code was asserting that it shouldn't assume the call return type matches that of the callee for a call to a builtin<br>
<br>
<br>
<br>
</span>I'd feel more comfortable representing this with a cast, as I'd rather not carve out an exception to a reasonable AST invariant.<br>
<span class=""><br>
<br>
<br>
> I guess this is probably the ExprClassification.cpp code?<br>
<br>
<br>
<br>
</span>Yes.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<a href="http://reviews.llvm.org/D6332" target="_blank">http://reviews.llvm.org/D6332</a><br>
<br>
<br>
<br>
EMAIL PREFERENCES<br>
<br>
  <a href="http://reviews.llvm.org/settings/panel/emailpreferences/" target="_blank">http://reviews.llvm.org/settings/panel/emailpreferences/</a><br>
<br>
<br>
<br>
<br>
</div></div></blockquote></div><br></div></div>