bool IsVirtual : 1;
bool IsPure : 1;
bool InheritedPrototype : 1;
+ bool IsDeleted : 1;
// Move to DeclGroup when it is implemented.
SourceLocation TypeSpecStartLoc;
DeclContext(DK),
ParamInfo(0), Body(0), PreviousDeclaration(0),
SClass(S), IsInline(isInline), IsVirtual(false), IsPure(false),
- InheritedPrototype(false), TypeSpecStartLoc(TSSL) {}
+ InheritedPrototype(false), IsDeleted(false), TypeSpecStartLoc(TSSL) {}
virtual ~FunctionDecl() {}
virtual void Destroy(ASTContext& C);
bool inheritedPrototype() { return InheritedPrototype; }
void setInheritedPrototype() { InheritedPrototype = true; }
+ /// \brief Whether this function has been deleted.
+ ///
+ /// A function that is "deleted" (via the C++0x "= delete" syntax)
+ /// acts like a normal function, except that it cannot actually be
+ /// called or have its address taken. Deleted functions are
+ /// typically used in C++ overload resolution to attract arguments
+ /// whose type or lvalue/rvalue-ness would permit the use of a
+ /// different overload that would behave incorrectly. For example,
+ /// one might use deleted functions to ban implicit conversion from
+ /// a floating-point number to an Integer type:
+ ///
+ /// @code
+ /// struct Integer {
+ /// Integer(long); // construct from a long
+ /// Integer(double) = delete; // no construction from float or double
+ /// Integer(long double) = delete; // no construction from long double
+ /// };
+ /// @endcode
+ bool isDeleted() const { return IsDeleted; }
+ void setDeleted() { IsDeleted = true; }
+
/// getPreviousDeclaration - Return the previous declaration of this
/// function.
const FunctionDecl *getPreviousDeclaration() const {
"no matching member function for call to %0")
DIAG(err_ovl_ambiguous_call, ERROR,
"call to %0 is ambiguous")
+DIAG(err_ovl_deleted_call, ERROR,
+ "call to %select{unavailable|deleted}0 function %1")
DIAG(err_ovl_ambiguous_member_call, ERROR,
"call to member function %0 is ambiguous")
+DIAG(err_ovl_deleted_member_call, ERROR,
+ "call to %select{unavailable|deleted}0 member function %1")
DIAG(err_ovl_candidate, NOTE,
"candidate function")
+DIAG(err_ovl_candidate_deleted, NOTE,
+ "candidate function has been explicitly %select{made unavailable|deleted}0")
DIAG(err_ovl_builtin_candidate, NOTE,
"built-in candidate function %0")
DIAG(err_ovl_no_viable_function_in_init, ERROR,
"no matching constructor for initialization of %0")
DIAG(err_ovl_ambiguous_init, ERROR,
"call to constructor of %0 is ambiguous")
+DIAG(err_ovl_deleted_init, ERROR,
+ "call to %select{unavailable|deleted}0 constructor of %1")
DIAG(err_ovl_ambiguous_oper, ERROR,
"use of overloaded operator '%0' is ambiguous")
DIAG(err_ovl_no_viable_oper, ERROR,
"no viable overloaded '%0'")
+DIAG(err_ovl_deleted_oper, ERROR,
+ "overload resolution selected %select{unavailable|deleted}0 operator '%1'")
+
DIAG(err_ovl_no_viable_object_call, ERROR,
"no matching function for call to object of type %0")
DIAG(err_ovl_ambiguous_object_call, ERROR,
"call to object of type %0 is ambiguous")
+DIAG(err_ovl_deleted_object_call, ERROR,
+ "call to %select{unavailable|deleted}0 function call operator in type %1")
DIAG(err_ovl_surrogate_cand, NOTE,
"conversion candidate of type %0")
DIAG(err_member_call_without_object, ERROR,
"%0 is deprecated")
DIAG(warn_unavailable, WARNING,
"%0 is unavailable")
+DIAG(note_unavailable_here, NOTE,
+ "function has been explicitly marked %select{unavailable|deleted}0 here")
DIAG(err_redefinition, ERROR,
"redefinition of %0")
DIAG(err_static_non_static, ERROR,
"too few arguments to %select{function|block|method}0 call")
DIAG(err_typecheck_call_too_many_args, ERROR,
"too many arguments to %select{function|block|method}0 call")
-DIAG(err_call_deleted_function, ERROR,
- "call to function %1 that has been intentionally %select{deleted|made unavailable}0 ")
-DIAG(note_deleted_function_here, NOTE,
- "%select{deleted|unavailable}0 function is declared here")
+DIAG(err_deleted_function_use, ERROR,
+ "attempt to use a deleted function")
DIAG(warn_cannot_pass_non_pod_arg_to_vararg, WARNING,
"cannot pass object of non-POD type %0 through variadic "
"%select{function|block|method}1; call will abort at runtime")
enum OverloadingResult {
OR_Success, ///< Overload resolution succeeded.
OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous ///< Ambiguous candidates found.
+ OR_Ambiguous, ///< Ambiguous candidates found.
+ OR_Deleted ///< Overload resoltuion refers to a deleted function.
};
void AddOverloadCandidate(FunctionDecl *Function,
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.
- /// DiagnoseUseOfDeprecatedDecl - If the specified decl is deprecated or
- // unavailable, emit the corresponding diagnostics.
- inline void DiagnoseUseOfDeprecatedDecl(NamedDecl *D, SourceLocation Loc) {
- if (D->hasAttrs())
- DiagnoseUseOfDeprecatedDeclImpl(D, Loc);
- }
- void DiagnoseUseOfDeprecatedDeclImpl(NamedDecl *D, SourceLocation Loc);
+ bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
-
// Primary Expressions.
virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II,
if (IIDecl) {
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
- // If this typename is deprecated, emit a warning.
- DiagnoseUseOfDeprecatedDecl(IIDecl, NameLoc);
+ // Check whether we can use this type
+ (void)DiagnoseUseOfDecl(IIDecl, NameLoc);
return Context.getTypeDeclType(TD).getAsOpaquePtr();
}
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
- // If this typename is deprecated, emit a warning.
- DiagnoseUseOfDeprecatedDecl(IIDecl, NameLoc);
+ // Check whether we can use this interface.
+ (void)DiagnoseUseOfDecl(IIDecl, NameLoc);
return Context.getObjCInterfaceType(IDecl).getAsOpaquePtr();
}
if (OldQType == NewQType) {
// We have a redeclaration.
MergeAttributes(New, Old);
+
+ // Merge the "deleted" flag.
+ if (Old->isDeleted())
+ New->setDeleted();
+
return MergeCXXFunctionDecl(New, Old);
}
}
MergeAttributes(New, Old);
+
+ // Merge the "deleted" flag.
+ if (Old->isDeleted())
+ New->setDeleted();
return false;
}
}
if (PrevDecl) {
- // If the previous declaration was deprecated, emit a warning.
- DiagnoseUseOfDeprecatedDecl(PrevDecl, NameLoc);
+ // Check whether the previous declaration is usable.
+ (void)DiagnoseUseOfDecl(PrevDecl, NameLoc);
if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
// If this is a use of a previous tag, or if the tag is already declared
Diag(Loc, diag::err_ovl_ambiguous_init) << ClassType << Range;
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return 0;
+
+ case OR_Deleted:
+ if (InitEntity)
+ Diag(Loc, diag::err_ovl_deleted_init)
+ << Best->Function->isDeleted()
+ << InitEntity << Range;
+ else
+ Diag(Loc, diag::err_ovl_deleted_init)
+ << Best->Function->isDeleted()
+ << InitEntity << Range;
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return 0;
}
return 0;
if (Fn) {
// Since we're performing this reference-initialization for
// real, update the initializer with the resulting function.
- if (!ICS)
+ if (!ICS) {
+ if (DiagnoseUseOfDecl(Fn, Init->getSourceRange().getBegin()))
+ return true;
+
FixOverloadedFunctionReference(Init, Fn);
+ }
T2 = Fn->getType();
}
return true;
case OR_No_Viable_Function:
- // There was no suitable conversion; continue with other checks.
+ case OR_Deleted:
+ // There was no suitable conversion, or we found a deleted
+ // conversion; continue with other checks.
break;
}
}
// Diagnose classes that inherit from deprecated classes.
if (SuperClassDecl)
- DiagnoseUseOfDeprecatedDecl(SuperClassDecl, SuperLoc);
+ (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
if (PrevDecl && SuperClassDecl == 0) {
// The previous declaration was not a class decl. Check if we have a
continue;
}
- DiagnoseUseOfDeprecatedDecl(PDecl, ProtocolId[i].second);
+ (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
// If this is a forward declaration and we are supposed to warn in this
// case, do it.
CDecl->setClassInterface(IDecl);
// If the interface is deprecated, warn about it.
- DiagnoseUseOfDeprecatedDecl(IDecl, ClassLoc);
+ (void)DiagnoseUseOfDecl(IDecl, ClassLoc);
/// Check for duplicate interface declaration for this category
ObjCCategoryDecl *CDeclChain;
#include "clang/Parse/Scope.h"
using namespace clang;
-
-/// DiagnoseUseOfDeprecatedDeclImpl - If the specified decl is deprecated or
-// unavailable, emit the corresponding diagnostics.
-void Sema::DiagnoseUseOfDeprecatedDeclImpl(NamedDecl *D, SourceLocation Loc) {
+/// \brief Determine whether the use of this declaration is valid, and
+/// emit any corresponding diagnostics.
+///
+/// This routine diagnoses various problems with referencing
+/// declarations that can occur when using a declaration. For example,
+/// it might warn if a deprecated or unavailable declaration is being
+/// used, or produce an error (and return true) if a C++0x deleted
+/// function is being used.
+///
+/// \returns true if there was an error (this declaration cannot be
+/// referenced), false otherwise.
+bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is deprecated.
if (D->getAttr<DeprecatedAttr>()) {
- // Implementing deprecated stuff requires referencing depreated stuff. Don't
- // warn if we are implementing a deprecated construct.
+ // Implementing deprecated stuff requires referencing deprecated
+ // stuff. Don't warn if we are implementing a deprecated
+ // construct.
bool isSilenced = false;
if (NamedDecl *ND = getCurFunctionOrMethodDecl()) {
Diag(Loc, diag::warn_deprecated) << D->getDeclName();
}
- // See if hte decl is unavailable.
- if (D->getAttr<UnavailableAttr>())
+ // See if this is a deleted function.
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isDeleted()) {
+ Diag(Loc, diag::err_deleted_function_use);
+ Diag(D->getLocation(), diag::note_unavailable_here) << true;
+ return true;
+ }
+
+ // See if the decl is unavailable
+ if (D->getAttr<UnavailableAttr>()) {
Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+ Diag(D->getLocation(), diag::note_unavailable_here) << 0;
+ }
+
+
+ return false;
}
//===----------------------------------------------------------------------===//
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) {
// Check if referencing a field with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(IV, Loc);
+ if (DiagnoseUseOfDecl(IV, Loc))
+ return ExprError();
// FIXME: This should use a new expr for a direct reference, don't turn
// this into Self->ivar, just return a BareIVarExpr or something.
}
}
- if (getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
- HasTrailingLParen && D == 0) {
+ // Determine whether this name might be a candidate for
+ // argument-dependent lookup.
+ bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
+ HasTrailingLParen;
+
+ if (ADL && D == 0) {
// We've seen something of the form
//
// identifier(
false, false, SS));
ValueDecl *VD = cast<ValueDecl>(D);
- // Check if referencing an identifier with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(VD, Loc);
-
+ // Check whether this declaration can be used. Note that we suppress
+ // this check when we're going to perform argument-dependent lookup
+ // on this function name, because this might not be the function
+ // that overload resolution actually selects.
+ if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
+ return ExprError();
+
if (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
// Warn about constructs like:
// if (void *X = foo()) { ... } else { X }.
<< Arg->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return ExprError();
+
+ case OR_Deleted:
+ Diag(OpLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << UnaryOperator::getOpcodeStr(Opc)
+ << Arg->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return ExprError();
}
// Either we found no viable overloaded operator or we matched a
<< LHSExp->getSourceRange() << RHSExp->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return ExprError();
+
+ case OR_Deleted:
+ Diag(LLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << "[]"
+ << LHSExp->getSourceRange() << RHSExp->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return ExprError();
}
// Either we found no viable overloaded operator or we matched a
if (MemberDecl->isInvalidDecl())
return ExprError();
- // Check if referencing a field with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(MemberDecl, MemberLoc);
+ // Check the use of this field
+ if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
+ return ExprError();
if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
// We may have found a field within an anonymous union or struct
// error cases.
if (IV->isInvalidDecl())
return ExprError();
-
- // Check if referencing a field with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(IV, MemberLoc);
+
+ // Check whether we can reference this field.
+ if (DiagnoseUseOfDecl(IV, MemberLoc))
+ return ExprError();
ObjCIvarRefExpr *MRef= new (Context) ObjCIvarRefExpr(IV, IV->getType(),
MemberLoc, BaseExpr,
// Search for a declared property first.
if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) {
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(PD, MemberLoc);
+ // Check whether we can reference this property.
+ if (DiagnoseUseOfDecl(PD, MemberLoc))
+ return ExprError();
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
MemberLoc, BaseExpr));
for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(),
E = IFTy->qual_end(); I != E; ++I)
if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(PD, MemberLoc);
+ // Check whether we can reference this property.
+ if (DiagnoseUseOfDecl(PD, MemberLoc))
+ return ExprError();
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
MemberLoc, BaseExpr));
}
}
if (Getter) {
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(Getter, MemberLoc);
+ // Check if we can reference this property.
+ if (DiagnoseUseOfDecl(Getter, MemberLoc))
+ return ExprError();
// If we found a getter then this may be a valid dot-reference, we
// will look for the matching setter, in case it is needed.
}
}
- if (Setter)
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(Setter, MemberLoc);
-
+ if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+ return ExprError();
// FIXME: we must check that the setter has property type.
return Owned(new (Context) ObjCKVCRefExpr(Getter, Getter->getResultType(),
for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
E = QIdTy->qual_end(); I != E; ++I) {
if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(PD, MemberLoc);
+ // Check the use of this declaration
+ if (DiagnoseUseOfDecl(PD, MemberLoc))
+ return ExprError();
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
MemberLoc, BaseExpr));
// Also must look for a getter name which uses property syntax.
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
- // Check if referencing a property with __attribute__((deprecated)).
- DiagnoseUseOfDeprecatedDecl(OMD, MemberLoc);
+ // Check the use of this method.
+ if (DiagnoseUseOfDecl(OMD, MemberLoc))
+ return ExprError();
return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel,
OMD->getResultType(), OMD, OpLoc, MemberLoc, NULL, 0));
Context.BoolTy,
RParenLoc));
- // Check for a call to a (FIXME: deleted) or unavailable function.
- if (FDecl && FDecl->getAttr<UnavailableAttr>()) {
- Diag(Fn->getSourceRange().getBegin(), diag::err_call_deleted_function)
- << FDecl->getAttr<UnavailableAttr>() << FDecl->getDeclName()
- << Fn->getSourceRange();
- Diag(FDecl->getLocation(), diag::note_deleted_function_here)
- << FDecl->getAttr<UnavailableAttr>();
- return ExprError();
- }
-
const FunctionType *FuncT;
if (!Fn->getType()->isBlockPointerType()) {
// C99 6.5.2.2p1 - "The expression that denotes the called function shall
<< lhs->getSourceRange() << rhs->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return ExprError();
+
+ case OR_Deleted:
+ Diag(TokLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << BinaryOperator::getOpcodeStr(Opc)
+ << lhs->getSourceRange() << rhs->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return ExprError();
}
// Either we found no viable overloaded operator or we matched a
<< Input->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return ExprError();
+
+ case OR_Deleted:
+ Diag(OpLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << UnaryOperator::getOpcodeStr(Opc)
+ << Input->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return ExprError();
}
// Either we found no viable overloaded operator or we matched a
<< Name << Range;
PrintOverloadCandidates(Candidates, /*OnlyViable=*/true);
return true;
+
+ case OR_Deleted:
+ Diag(StartLoc, diag::err_ovl_deleted_call)
+ << Best->Function->isDeleted()
+ << Name << Range;
+ PrintOverloadCandidates(Candidates, /*OnlyViable=*/true);
+ return true;
}
assert(false && "Unreachable, bad result from BestViableFunction");
return true;
break;
case ICK_Array_To_Pointer:
+ FromType = Context.getArrayDecayedType(FromType);
+ ImpCastExprToType(From, FromType);
+ break;
+
+ case ICK_Function_To_Pointer:
if (FromType->isOverloadType()) {
FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, true);
if (!Fn)
return true;
+ if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
+ return true;
+
FixOverloadedFunctionReference(From, Fn);
FromType = From->getType();
- } else {
- FromType = Context.getArrayDecayedType(FromType);
}
- ImpCastExprToType(From, FromType);
- break;
-
- case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType);
ImpCastExprToType(From, FromType);
break;
if (!Method)
Method = ClassDecl->lookupInstanceMethod(Sel);
- if (Method)
- DiagnoseUseOfDeprecatedDecl(Method, receiverLoc);
+ if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+ return true;
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true,
lbrac, rbrac, returnType))
Method = SuperDecl->lookupInstanceMethod(Sel);
}
- if (Method)
- DiagnoseUseOfDeprecatedDecl(Method, receiverLoc);
+ if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+ return true;
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
lbrac, rbrac, returnType))
ObjCImplementations[ClassDecl->getIdentifier()])
Method = ImpDecl->getClassMethod(Sel);
- if (Method)
- DiagnoseUseOfDeprecatedDecl(Method, receiverLoc);
+ if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+ return true;
}
if (!Method)
Method = FactoryMethodPool[Sel].Method;
Diag(lbrac, diag::warn_method_not_found_in_protocol)
<< Sel << SourceRange(lbrac, rbrac);
- if (Method)
- DiagnoseUseOfDeprecatedDecl(Method, receiverLoc);
+ if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+ return true;
} else {
Diag(lbrac, diag::error_bad_receiver_type)
<< RExpr->getType() << RExpr->getSourceRange();
}
case OR_No_Viable_Function:
+ case OR_Deleted:
// No conversion here! We're done.
return false;
}
// Best is the best viable function.
+ if (Best->Function &&
+ (Best->Function->isDeleted() ||
+ Best->Function->getAttr<UnavailableAttr>()))
+ return OR_Deleted;
+
+ // If Best refers to a function that is either deleted (C++0x) or
+ // unavailable (Clang extension) report an error.
+
return OR_Success;
}
for (; Cand != LastCand; ++Cand) {
if (Cand->Viable || !OnlyViable) {
if (Cand->Function) {
- // Normal function
- Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
+ if (Cand->Function->isDeleted() ||
+ Cand->Function->getAttr<UnavailableAttr>()) {
+ // Deleted or "unavailable" function.
+ Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted)
+ << Cand->Function->isDeleted();
+ } else {
+ // Normal function
+ // FIXME: Give a better reason!
+ Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
+ }
} else if (Cand->IsSurrogate) {
// Desugar the type of the surrogate down to a function type,
// retaining as many typedefs as possible while still showing
<< UnqualifiedName << Fn->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
break;
+
+ case OR_Deleted:
+ Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_deleted_call)
+ << Best->Function->isDeleted()
+ << UnqualifiedName
+ << Fn->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ break;
}
// Overload resolution failed. Destroy all of the subexpressions and
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
// FIXME: Leaking incoming expressions!
return true;
+
+ case OR_Deleted:
+ Diag(MemExpr->getSourceRange().getBegin(),
+ diag::err_ovl_deleted_member_call)
+ << Best->Function->isDeleted()
+ << Ovl->getDeclName() << MemExprE->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+ // FIXME: Leaking incoming expressions!
+ return true;
}
FixOverloadedFunctionReference(MemExpr, Method);
<< Object->getType() << Object->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
break;
+
+ case OR_Deleted:
+ Diag(Object->getSourceRange().getBegin(),
+ diag::err_ovl_deleted_object_call)
+ << Best->Function->isDeleted()
+ << Object->getType() << Object->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ break;
}
if (Best == CandidateSet.end()) {
<< "operator->" << BasePtr->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return true;
+
+ case OR_Deleted:
+ Diag(OpLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << "operator->" << BasePtr->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ return true;
}
// Convert the object parameter.
ImpCastExprToType(Arg, ArgType);
} else if (FunctionDecl *Fn
= ResolveAddressOfOverloadedFunction(Arg, ParamType, true)) {
+ if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
+ return true;
+
FixOverloadedFunctionReference(Arg, Fn);
ArgType = Arg->getType();
if (ArgType->isFunctionType() && ParamType->isPointerType()) {
void promote() __attribute__((__overloadable__)); // expected-error{{'overloadable' function 'promote' must have a prototype}}
void promote(...) __attribute__((__overloadable__, __unavailable__)); // \
- // expected-note{{unavailable function is declared here}}
+ // expected-note{{candidate function}}
void test_promote(short* sp) {
promote(1.0);
- promote(sp); // expected-error{{call to function 'promote' that has been intentionally made unavailable}}
+ promote(sp); // expected-error{{call to unavailable function 'promote'}}
}
int &foo(int);
double &foo(double);
-void foo(...) __attribute__((__unavailable__)); // expected-note{{unavailable function is declared here}}
+void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
+// expected-note{{function has been explicitly marked unavailable here}}
+
+void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}}
void test_foo(short* sp) {
int &ir = foo(1);
double &dr = foo(1.0);
- foo(sp); // expected-error{{call to function 'foo' that has been intentionally made unavailable}}
+ foo(sp); // expected-error{{call to unavailable function 'foo'}}
+
+ void (*fp)(...) = &bar; // expected-warning{{'bar' is unavailable}}
+ void (*fp2)(...) = bar; // expected-warning{{'bar' is unavailable}}
+
+ int &(*fp3)(int) = foo;
+ void (*fp4)(...) = foo; // expected-warning{{'foo' is unavailable}}
}
// RUN: clang -fsyntax-only -verify %s
__attribute ((unavailable))
-@protocol FwProto;
+@protocol FwProto; // expected-note{{marked unavailable}}
Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}}
Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}}
-@protocol FwProto @end
+@protocol FwProto @end // expected-note{{marked unavailable}}
@interface MyClass2 <FwProto> // expected-warning {{'FwProto' is unavailable}}
@end
-__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto;
+__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto; // expected-note{{marked unavailable}}
id <XProto> idX = 0; // expected-warning {{'XProto' is unavailable}} expected-warning {{'XProto' is deprecated}}