|
@@ -2508,7 +2508,8 @@ enum {
|
|
|
ft_parameter_arity,
|
|
|
ft_parameter_mismatch,
|
|
|
ft_return_type,
|
|
|
- ft_qualifer_mismatch
|
|
|
+ ft_qualifer_mismatch,
|
|
|
+ ft_addr_enable_if
|
|
|
};
|
|
|
|
|
|
/// HandleFunctionTypeMismatch - Gives diagnostic information for differeing
|
|
@@ -8683,20 +8684,37 @@ void MaybeEmitInheritedConstructorNote(Sema &S, Decl *Fn) {
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
+static bool isFunctionAlwaysEnabled(const ASTContext &Ctx,
|
|
|
+ const FunctionDecl *FD) {
|
|
|
+ for (auto *EnableIf : FD->specific_attrs<EnableIfAttr>()) {
|
|
|
+ bool AlwaysTrue;
|
|
|
+ if (!EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx))
|
|
|
+ return false;
|
|
|
+ if (!AlwaysTrue)
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
// Notes the location of an overload candidate.
|
|
|
-void Sema::NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType) {
|
|
|
+void Sema::NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType,
|
|
|
+ bool TakingAddress) {
|
|
|
std::string FnDesc;
|
|
|
OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc);
|
|
|
PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)
|
|
|
<< (unsigned) K << FnDesc;
|
|
|
- HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
|
|
|
+ if (TakingAddress && !isFunctionAlwaysEnabled(Context, Fn))
|
|
|
+ PD << ft_addr_enable_if;
|
|
|
+ else
|
|
|
+ HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
|
|
|
Diag(Fn->getLocation(), PD);
|
|
|
MaybeEmitInheritedConstructorNote(*this, Fn);
|
|
|
}
|
|
|
|
|
|
// Notes the location of all overload candidates designated through
|
|
|
// OverloadedExpr
|
|
|
-void Sema::NoteAllOverloadCandidates(Expr* OverloadedExpr, QualType DestType) {
|
|
|
+void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType,
|
|
|
+ bool TakingAddress) {
|
|
|
assert(OverloadedExpr->getType() == Context.OverloadTy);
|
|
|
|
|
|
OverloadExpr::FindResult Ovl = OverloadExpr::find(OverloadedExpr);
|
|
@@ -8707,10 +8725,11 @@ void Sema::NoteAllOverloadCandidates(Expr* OverloadedExpr, QualType DestType) {
|
|
|
I != IEnd; ++I) {
|
|
|
if (FunctionTemplateDecl *FunTmpl =
|
|
|
dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) {
|
|
|
- NoteOverloadCandidate(FunTmpl->getTemplatedDecl(), DestType);
|
|
|
+ NoteOverloadCandidate(FunTmpl->getTemplatedDecl(), DestType,
|
|
|
+ TakingAddress);
|
|
|
} else if (FunctionDecl *Fun
|
|
|
= dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) {
|
|
|
- NoteOverloadCandidate(Fun, DestType);
|
|
|
+ NoteOverloadCandidate(Fun, DestType, TakingAddress);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -10035,7 +10054,12 @@ private:
|
|
|
Specialization = cast<FunctionDecl>(Specialization->getCanonicalDecl());
|
|
|
assert(S.isSameOrCompatibleFunctionType(
|
|
|
Context.getCanonicalType(Specialization->getType()),
|
|
|
- Context.getCanonicalType(TargetFunctionType)));
|
|
|
+ Context.getCanonicalType(TargetFunctionType)) ||
|
|
|
+ (!S.getLangOpts().CPlusPlus && TargetType->isVoidPointerType()));
|
|
|
+
|
|
|
+ if (!isFunctionAlwaysEnabled(S.Context, Specialization))
|
|
|
+ return false;
|
|
|
+
|
|
|
Matches.push_back(std::make_pair(CurAccessFunPair, Specialization));
|
|
|
return true;
|
|
|
}
|
|
@@ -10066,13 +10090,17 @@ private:
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ if (!isFunctionAlwaysEnabled(S.Context, FunDecl))
|
|
|
+ return false;
|
|
|
+
|
|
|
QualType ResultTy;
|
|
|
if (Context.hasSameUnqualifiedType(TargetFunctionType,
|
|
|
FunDecl->getType()) ||
|
|
|
S.IsNoReturnConversion(FunDecl->getType(), TargetFunctionType,
|
|
|
- ResultTy)) {
|
|
|
- Matches.push_back(std::make_pair(CurAccessFunPair,
|
|
|
- cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
|
|
|
+ ResultTy) ||
|
|
|
+ (!S.getLangOpts().CPlusPlus && TargetType->isVoidPointerType())) {
|
|
|
+ Matches.push_back(std::make_pair(
|
|
|
+ CurAccessFunPair, cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
|
|
|
FoundNonTemplateFunction = true;
|
|
|
return true;
|
|
|
}
|
|
@@ -10174,7 +10202,8 @@ public:
|
|
|
<< OvlExpr->getName() << TargetFunctionType
|
|
|
<< OvlExpr->getSourceRange();
|
|
|
if (FailedCandidates.empty())
|
|
|
- S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType);
|
|
|
+ S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType,
|
|
|
+ /*TakingAddress=*/true);
|
|
|
else {
|
|
|
// We have some deduction failure messages. Use them to diagnose
|
|
|
// the function templates, and diagnose the non-template candidates
|
|
@@ -10184,7 +10213,8 @@ public:
|
|
|
I != IEnd; ++I)
|
|
|
if (FunctionDecl *Fun =
|
|
|
dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
|
|
|
- S.NoteOverloadCandidate(Fun, TargetFunctionType);
|
|
|
+ S.NoteOverloadCandidate(Fun, TargetFunctionType,
|
|
|
+ /*TakingAddress=*/true);
|
|
|
FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart());
|
|
|
}
|
|
|
}
|
|
@@ -10222,7 +10252,8 @@ public:
|
|
|
S.Diag(OvlExpr->getLocStart(), diag::err_addr_ovl_ambiguous)
|
|
|
<< OvlExpr->getName()
|
|
|
<< OvlExpr->getSourceRange();
|
|
|
- S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType);
|
|
|
+ S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType,
|
|
|
+ /*TakingAddress=*/true);
|
|
|
}
|
|
|
|
|
|
bool hadMultipleCandidates() const { return (OvlExpr->getNumDecls() > 1); }
|