summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2018-12-21 07:05:36 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2018-12-21 07:05:36 +0000
commit24b719c0fc2b1251a37741a2339ffcfe9cdcd475 (patch)
treebf8ec7f429da912c28cb060306760cc1d8f16c7d /lib/Sema/SemaExprCXX.cpp
parent4e2a388a999e41a12743314deb9e0f060252a621 (diff)
[Sema] Produce diagnostics when C++17 aligned allocation/deallocation
functions that are unavailable on Darwin are explicitly called or called from deleting destructors. rdar://problem/40736230 Differential Revision: https://reviews.llvm.org/D47757 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp45
1 files changed, 25 insertions, 20 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 2b054c4b0f..18d0e78a4f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1744,28 +1744,33 @@ static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
return false;
}
-// Emit a diagnostic if an aligned allocation/deallocation function that is not
-// implemented in the standard library is selected.
-static void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
- SourceLocation Loc, bool IsDelete,
- Sema &S) {
- if (!S.getLangOpts().AlignedAllocationUnavailable)
- return;
-
- // Return if there is a definition.
+bool
+Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const {
+ if (!getLangOpts().AlignedAllocationUnavailable)
+ return false;
if (FD.isDefined())
- return;
-
+ return false;
bool IsAligned = false;
- if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) {
- const llvm::Triple &T = S.getASTContext().getTargetInfo().getTriple();
+ if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned)
+ return true;
+ return false;
+}
+
+// Emit a diagnostic if an aligned allocation/deallocation function that is not
+// implemented in the standard library is selected.
+void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+ SourceLocation Loc) {
+ if (isUnavailableAlignedAllocationFunction(FD)) {
+ const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
- S.getASTContext().getTargetInfo().getPlatformName());
+ getASTContext().getTargetInfo().getPlatformName());
- S.Diag(Loc, diag::err_aligned_allocation_unavailable)
+ OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator();
+ bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete;
+ Diag(Loc, diag::err_aligned_allocation_unavailable)
<< IsDelete << FD.getType().getAsString() << OSName
<< alignedAllocMinVersion(T.getOS()).getAsString();
- S.Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
+ Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
}
}
@@ -2149,13 +2154,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
return ExprError();
MarkFunctionReferenced(StartLoc, OperatorNew);
- diagnoseUnavailableAlignedAllocation(*OperatorNew, StartLoc, false, *this);
}
if (OperatorDelete) {
if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
return ExprError();
MarkFunctionReferenced(StartLoc, OperatorDelete);
- diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true, *this);
}
// C++0x [expr.new]p17:
@@ -3405,8 +3408,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
}
}
- diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true,
- *this);
+ DiagnoseUseOfDecl(OperatorDelete, StartLoc);
// Convert the operand to the type of the first parameter of operator
// delete. This is only necessary if we selected a destroying operator
@@ -3539,6 +3541,9 @@ Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
return ExprError();
assert(OperatorNewOrDelete && "should be found");
+ DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc());
+ MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete);
+
TheCall->setType(OperatorNewOrDelete->getReturnType());
for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {
QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType();