[PATCH] Implement the __builtin_call_with_static_chain GNU extension.
Peter Collingbourne
peter at pcc.me.uk
Thu Dec 11 01:26:16 PST 2014
================
Comment at: include/clang/Basic/Builtins.def:500
@@ -499,2 +499,3 @@
BUILTIN(__builtin_alloca, "v*z" , "n")
+BUILTIN(__builtin_call_with_static_chain, "v.", "t")
----------------
rsmith wrote:
> This should presumably also be marked "n"; it itself never throws (its argument might, but that's a separate issue).
Done.
================
Comment at: lib/Sema/SemaChecking.cpp:177-184
@@ +176,10 @@
+
+ ExprResult ChainResult = S.UsualUnaryConversions(Chain);
+ if (ChainResult.isInvalid())
+ return true;
+ if (!ChainResult.get()->getType()->isPointerType()) {
+ S.Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
+ << Chain->getSourceRange();
+ return true;
+ }
+
----------------
rsmith wrote:
> It might be better to perform conversions as if to a parameter of type `void *` here (that would be detectable in C++ via conversion operators, and would do the right thing for null pointer constants). What does GCC do in those cases?
GCC appears to only support the extension in C mode, not in C++. It appears to check the second argument's type rather than attempting any implicit conversions, so null pointer constants are rejected. I couldn't identify any cases (in C) where we reject a second argument that GCC accepts or vice versa.
================
Comment at: lib/Sema/SemaChecking.cpp:187
@@ +186,3 @@
+ BuiltinCall->setType(CE->getType());
+ BuiltinCall->getCallee()->setType(CE->getCallee()->getType());
+ BuiltinCall->setValueKind(CE->getValueKind());
----------------
rsmith wrote:
> 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?
I found this to be necessary in cases where the function returns an lvalue; without it, I was getting assertion failures.
I thought this might be an issue as well, until I looked at the AST representation of builtin calls:
```
| |-CallExpr 0x4310ae0 <col:3, col:42> 'int' lvalue
| | |-ImplicitCastExpr 0x4310ac8 <col:3> 'int &(*)(void)' <BuiltinFnToFnPtr>
| | | `-DeclRefExpr 0x4310960 <col:3> '<builtin fn type>' Function 0x43108c0 '__builtin_call_with_static_chain' 'void ()'
| | |-CallExpr 0x4310a50 <col:36, col:38> 'int' lvalue
| | | `-ImplicitCastExpr 0x4310a38 <col:36> 'int &(*)(void)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x43109e0 <col:36> 'int &(void)' lvalue Function 0x42ca430 'f' 'int &(void)'
| | `-ImplicitCastExpr 0x4310b18 <col:41> 'int &(*)(void)' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x4310a78 <col:41> 'int &(void)' lvalue Function 0x42ca430 'f' 'int &(void)'
```
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).
http://reviews.llvm.org/D6332
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the cfe-commits
mailing list