aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-05-04 06:44:46 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-05-04 06:44:46 +0000
commit82f145d4ed86d19cb2a1680cda53fdc39bb38eb6 (patch)
tree64406c74e519c1114a39fa7721938b231b530d00
parentffd015e316fff53f23e9ffd4907b88b8706e4183 (diff)
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). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181107 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExprCXX.cpp21
-rw-r--r--lib/Sema/SemaInit.cpp21
-rw-r--r--lib/Sema/SemaOverload.cpp13
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp4
4 files changed, 40 insertions, 19 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8d6924d6b1..dcc7ad7d0c 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -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;
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 3960deaa6c..6bbbcdc17a 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -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();
}
}
}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index dcd5318d3f..480c4a0d2b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -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
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
index d55de08144..1ed93b1375 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
@@ -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;