diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2016-01-07 02:26:57 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2016-01-07 02:26:57 +0000 |
commit | 7204ed97dd930e0cb159985a5973bc9993740726 (patch) | |
tree | 3422df717a6c911af7f97fdc06baca35553b5055 /clang/lib/Sema/SemaExpr.cpp | |
parent | 103d2381d67cef5cc0febed84da7bdd01d1a2cb1 (diff) | |
download | bcm5719-llvm-7204ed97dd930e0cb159985a5973bc9993740726.tar.gz bcm5719-llvm-7204ed97dd930e0cb159985a5973bc9993740726.zip |
[Sema] Teach overload resolution about unaddressable functions.
Given an expression like `(&Foo)();`, we perform overload resolution as
if we are calling `Foo` directly. This causes problems if `Foo` is a
function that can't have its address taken. This patch teaches overload
resolution to ignore functions that can't have their address taken in
such cases.
Differential Revision: http://reviews.llvm.org/D15590
llvm-svn: 257016
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8e50d5a103c..67d5db15cf2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4935,7 +4935,9 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, OverloadExpr *ovl = find.Expression; if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl)) return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, ArgExprs, - RParenLoc, ExecConfig); + RParenLoc, ExecConfig, + /*AllowTypoCorrection=*/true, + find.IsAddressOfOperand); return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs, RParenLoc); } } @@ -4949,10 +4951,14 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, Expr *NakedFn = Fn->IgnoreParens(); + bool CallingNDeclIndirectly = false; NamedDecl *NDecl = nullptr; - if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(NakedFn)) - if (UnOp->getOpcode() == UO_AddrOf) + if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(NakedFn)) { + if (UnOp->getOpcode() == UO_AddrOf) { + CallingNDeclIndirectly = true; NakedFn = UnOp->getSubExpr()->IgnoreParens(); + } + } if (isa<DeclRefExpr>(NakedFn)) { NDecl = cast<DeclRefExpr>(NakedFn)->getDecl(); @@ -4974,6 +4980,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl(); if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(NDecl)) { + if (CallingNDeclIndirectly && + !checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, + Fn->getLocStart())) + return ExprError(); + if (FD->hasAttr<EnableIfAttr>()) { if (const EnableIfAttr *Attr = CheckEnableIf(FD, ArgExprs, true)) { Diag(Fn->getLocStart(), |