Don't build a call expression referring to a function which we're not allowed
to use. This makes very little difference right now (other than suppressing follow-on errors in some cases), but will matter more once we support deduced return types (we don't want expressions with undeduced return types in the AST). llvm-svn: 181107
This commit is contained in:
parent
513db4d9f4
commit
22262abd78
|
@ -684,7 +684,8 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
|
|||
MarkFunctionReferenced(E->getExprLoc(), Destructor);
|
||||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_exception) << Ty);
|
||||
DiagnoseUseOfDecl(Destructor, E->getExprLoc());
|
||||
if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
|
||||
return ExprError();
|
||||
return Owned(E);
|
||||
}
|
||||
|
||||
|
@ -1426,11 +1427,13 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
|
||||
// Mark the new and delete operators as referenced.
|
||||
if (OperatorNew) {
|
||||
DiagnoseUseOfDecl(OperatorNew, StartLoc);
|
||||
if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
|
||||
return ExprError();
|
||||
MarkFunctionReferenced(StartLoc, OperatorNew);
|
||||
}
|
||||
if (OperatorDelete) {
|
||||
DiagnoseUseOfDecl(OperatorDelete, StartLoc);
|
||||
if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
|
||||
return ExprError();
|
||||
MarkFunctionReferenced(StartLoc, OperatorDelete);
|
||||
}
|
||||
|
||||
|
@ -1446,7 +1449,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
CheckDestructorAccess(StartLoc, dtor,
|
||||
PDiag(diag::err_access_dtor)
|
||||
<< BaseAllocType);
|
||||
DiagnoseUseOfDecl(dtor, StartLoc);
|
||||
if (DiagnoseUseOfDecl(dtor, StartLoc))
|
||||
return ExprError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2204,7 +2208,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
|
||||
MarkFunctionReferenced(StartLoc,
|
||||
const_cast<CXXDestructorDecl*>(Dtor));
|
||||
DiagnoseUseOfDecl(Dtor, StartLoc);
|
||||
if (DiagnoseUseOfDecl(Dtor, StartLoc))
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
// C++ [expr.delete]p3:
|
||||
|
@ -4819,7 +4824,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_temp)
|
||||
<< E->getType());
|
||||
DiagnoseUseOfDecl(Destructor, E->getExprLoc());
|
||||
if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
|
||||
return ExprError();
|
||||
|
||||
// If destructor is trivial, we can avoid the extra copy.
|
||||
if (Destructor->isTrivial())
|
||||
|
@ -4974,7 +4980,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
|
|||
CheckDestructorAccess(Bind->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_temp)
|
||||
<< Bind->getType());
|
||||
DiagnoseUseOfDecl(Destructor, Bind->getExprLoc());
|
||||
if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
|
||||
return ExprError();
|
||||
|
||||
// We need a cleanup, but we don't need to remember the temporary.
|
||||
ExprNeedsCleanups = true;
|
||||
|
|
|
@ -4867,7 +4867,8 @@ PerformConstructorInitialization(Sema &S,
|
|||
Kind.getKind() == InitializationKind::IK_Value)))) {
|
||||
// An explicitly-constructed temporary, e.g., X(1, 2).
|
||||
S.MarkFunctionReferenced(Loc, Constructor);
|
||||
S.DiagnoseUseOfDecl(Constructor, Loc);
|
||||
if (S.DiagnoseUseOfDecl(Constructor, Loc))
|
||||
return ExprError();
|
||||
|
||||
TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
|
||||
if (!TSInfo)
|
||||
|
@ -4926,7 +4927,8 @@ PerformConstructorInitialization(Sema &S,
|
|||
// Only check access if all of that succeeded.
|
||||
S.CheckConstructorAccess(Loc, Constructor, Entity,
|
||||
Step.Function.FoundDecl.getAccess());
|
||||
S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc);
|
||||
if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
|
||||
return ExprError();
|
||||
|
||||
if (shouldBindAsTemporary(Entity))
|
||||
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
|
||||
|
@ -5129,7 +5131,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
// Overload resolution determined which function invoke; update the
|
||||
// initializer to reflect that choice.
|
||||
S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
|
||||
S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
|
||||
if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
|
||||
return ExprError();
|
||||
CurInit = S.FixOverloadedFunctionReference(CurInit,
|
||||
Step->Function.FoundDecl,
|
||||
Step->Function.Function);
|
||||
|
@ -5265,7 +5268,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
|
||||
S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
|
||||
FoundFn.getAccess());
|
||||
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
|
||||
if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
|
||||
return ExprError();
|
||||
|
||||
CastKind = CK_ConstructorConversion;
|
||||
QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
|
||||
|
@ -5279,7 +5283,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
|
||||
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), 0,
|
||||
FoundFn);
|
||||
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
|
||||
if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
|
||||
return ExprError();
|
||||
|
||||
// FIXME: Should we move this initialization into a separate
|
||||
// derived-to-base conversion? I believe the answer is "no", because
|
||||
|
@ -5313,7 +5318,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor,
|
||||
S.PDiag(diag::err_access_dtor_temp) << T);
|
||||
S.MarkFunctionReferenced(CurInit.get()->getLocStart(), Destructor);
|
||||
S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart());
|
||||
if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart()))
|
||||
return ExprError();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5595,7 +5601,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
S.MarkFunctionReferenced(Kind.getLocation(), Destructor);
|
||||
S.CheckDestructorAccess(Kind.getLocation(), Destructor,
|
||||
S.PDiag(diag::err_access_dtor_temp) << E);
|
||||
S.DiagnoseUseOfDecl(Destructor, Kind.getLocation());
|
||||
if (S.DiagnoseUseOfDecl(Destructor, Kind.getLocation()))
|
||||
return ExprError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,13 +42,15 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
|
|||
bool HadMultipleCandidates,
|
||||
SourceLocation Loc = SourceLocation(),
|
||||
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
|
||||
if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
|
||||
return ExprError();
|
||||
|
||||
DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
|
||||
VK_LValue, Loc, LocInfo);
|
||||
if (HadMultipleCandidates)
|
||||
DRE->setHadMultipleCandidates(true);
|
||||
|
||||
S.MarkDeclRefReferenced(DRE);
|
||||
S.DiagnoseUseOfDecl(FoundDecl, Loc);
|
||||
|
||||
ExprResult E = S.Owned(DRE);
|
||||
E = S.DefaultFunctionArrayConversion(E.take());
|
||||
|
@ -9963,7 +9965,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
|
|||
case OR_Success: {
|
||||
FunctionDecl *FDecl = (*Best)->Function;
|
||||
SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
|
||||
SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
|
||||
if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()))
|
||||
return ExprError();
|
||||
Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
|
||||
return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
|
||||
RParenLoc, ExecConfig);
|
||||
|
@ -10846,7 +10849,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
|
|||
Method = cast<CXXMethodDecl>(Best->Function);
|
||||
FoundDecl = Best->FoundDecl;
|
||||
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
|
||||
if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
|
||||
return ExprError();
|
||||
break;
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
|
@ -11098,7 +11102,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
|
|||
Best->Conversions[0].UserDefined.ConversionFunction);
|
||||
|
||||
CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
|
||||
if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
|
||||
return ExprError();
|
||||
|
||||
// We selected one of the surrogate functions that converts the
|
||||
// object parameter to a function pointer. Perform the conversion
|
||||
|
|
|
@ -41,7 +41,9 @@ decltype(
|
|||
PD(), // expected-error {{private destructor}}
|
||||
PD()) pd1; // expected-error {{private destructor}}
|
||||
decltype(DD(), // expected-error {{deleted function}}
|
||||
DD()) dd1; // expected-error {{deleted function}}
|
||||
DD()) dd1;
|
||||
decltype(A(),
|
||||
DD()) dd2; // expected-error {{deleted function}}
|
||||
decltype(
|
||||
PD(), // expected-error {{temporary of type 'PD' has private destructor}}
|
||||
0) pd2;
|
||||
|
|
Loading…
Reference in New Issue