summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-01-07 02:26:57 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-01-07 02:26:57 +0000
commit7204ed97dd930e0cb159985a5973bc9993740726 (patch)
tree3422df717a6c911af7f97fdc06baca35553b5055 /clang/lib/Sema/SemaExpr.cpp
parent103d2381d67cef5cc0febed84da7bdd01d1a2cb1 (diff)
downloadbcm5719-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.cpp17
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(),
OpenPOWER on IntegriCloud