diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2018-12-21 07:05:36 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2018-12-21 07:05:36 +0000 |
commit | 24b719c0fc2b1251a37741a2339ffcfe9cdcd475 (patch) | |
tree | bf8ec7f429da912c28cb060306760cc1d8f16c7d /lib | |
parent | 4e2a388a999e41a12743314deb9e0f060252a621 (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')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 45 |
3 files changed, 34 insertions, 20 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d46aa23c27..8973d63255 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8288,6 +8288,7 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) { } } + DiagnoseUseOfDecl(OperatorDelete, Loc); MarkFunctionReferenced(Loc, OperatorDelete); Destructor->setOperatorDelete(OperatorDelete, ThisArg); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4ba0fb12e7..5178b03cfd 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -66,6 +66,12 @@ bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) { if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false)) return false; + + // See if this is an aligned allocation/deallocation function that is + // unavailable. + if (TreatUnavailableAsInvalid && + isUnavailableAlignedAllocationFunction(*FD)) + return false; } // See if this function is unavailable. @@ -228,6 +234,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, // The function 'main' shall not be used within a program. if (cast<FunctionDecl>(D)->isMain()) Diag(Loc, diag::ext_main_used); + + diagnoseUnavailableAlignedAllocation(*cast<FunctionDecl>(D), Loc); } // See if this is an auto-typed variable whose initializer we are parsing. 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(); |