forked from OSchip/llvm-project
When extracting the callee declaration from a call expression, be sure
to look through SubstNonTypeTemplateParmExprs. Then, update the IR generation of CallExprs to actually use CallExpr::getCalleeDecl() rather than attempting to mimick its behavior (badly). Fixes <rdar://problem/10063539>. llvm-svn: 139185
This commit is contained in:
parent
1762d7cc35
commit
e0e9630e07
|
@ -771,6 +771,12 @@ CallExpr::CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs,
|
|||
|
||||
Decl *CallExpr::getCalleeDecl() {
|
||||
Expr *CEE = getCallee()->IgnoreParenCasts();
|
||||
|
||||
while (SubstNonTypeTemplateParmExpr *NTTP
|
||||
= dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {
|
||||
CEE = NTTP->getReplacement()->IgnoreParenCasts();
|
||||
}
|
||||
|
||||
// If we're calling a dereference, look at the pointer instead.
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {
|
||||
if (BO->isPtrMemOp())
|
||||
|
|
|
@ -2174,14 +2174,10 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
|
|||
if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(E))
|
||||
return EmitCXXMemberCallExpr(CE, ReturnValue);
|
||||
|
||||
const Decl *TargetDecl = 0;
|
||||
if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
|
||||
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
|
||||
TargetDecl = DRE->getDecl();
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(TargetDecl))
|
||||
if (unsigned builtinID = FD->getBuiltinID())
|
||||
return EmitBuiltinExpr(FD, builtinID, E);
|
||||
}
|
||||
const Decl *TargetDecl = E->getCalleeDecl();
|
||||
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
|
||||
if (unsigned builtinID = FD->getBuiltinID())
|
||||
return EmitBuiltinExpr(FD, builtinID, E);
|
||||
}
|
||||
|
||||
if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
|
||||
|
|
|
@ -7,3 +7,15 @@ int main() {
|
|||
// CHECK: call signext i8 @memmove()
|
||||
return memmove();
|
||||
}
|
||||
|
||||
// <rdar://problem/10063539>
|
||||
|
||||
template<int (*Compare)(const char *s1, const char *s2)>
|
||||
int equal(const char *s1, const char *s2) {
|
||||
return Compare(s1, s2) == 0;
|
||||
}
|
||||
|
||||
// CHECK: define weak_odr i32 @_Z5equalIXadL_Z16__builtin_strcmpPKcS1_EEEiS1_S1_
|
||||
// CHECK: call i32 @strcmp
|
||||
template int equal<&__builtin_strcmp>(const char*, const char*);
|
||||
|
||||
|
|
Loading…
Reference in New Issue