summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-10-10 18:54:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-10-10 18:54:32 +0000
commitb2f0f057421309b628d51b4c260392d228c4993a (patch)
treea84dd329ce0b998b0c23edfd026e2c7c85156e7e /clang/lib/AST/Decl.cpp
parent50a92304aaa558130521129ab81fc8397efd5ee0 (diff)
downloadbcm5719-llvm-b2f0f057421309b628d51b4c260392d228c4993a.tar.gz
bcm5719-llvm-b2f0f057421309b628d51b4c260392d228c4993a.zip
Re-commit r283722, reverted in r283750, with a fix for a CUDA-specific use of
past-the-end iterator. Original commit message: P0035R4: Semantic analysis and code generation for C++17 overaligned allocation. llvm-svn: 283789
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp48
1 files changed, 35 insertions, 13 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index fec7df0ffb7..e330e31d47f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2596,7 +2596,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
return false;
const auto *FPT = getType()->castAs<FunctionProtoType>();
- if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
+ if (FPT->getNumParams() == 0 || FPT->getNumParams() > 3 || FPT->isVariadic())
return false;
// If this is a single-parameter function, it must be a replaceable global
@@ -2604,20 +2604,42 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
if (FPT->getNumParams() == 1)
return true;
- // Otherwise, we're looking for a second parameter whose type is
- // 'const std::nothrow_t &', or, in C++1y, 'std::size_t'.
- QualType Ty = FPT->getParamType(1);
+ unsigned Params = 1;
+ QualType Ty = FPT->getParamType(Params);
ASTContext &Ctx = getASTContext();
+
+ auto Consume = [&] {
+ ++Params;
+ Ty = Params < FPT->getNumParams() ? FPT->getParamType(Params) : QualType();
+ };
+
+ // In C++14, the next parameter can be a 'std::size_t' for sized delete.
+ bool IsSizedDelete = false;
if (Ctx.getLangOpts().SizedDeallocation &&
- Ctx.hasSameType(Ty, Ctx.getSizeType()))
- return true;
- if (!Ty->isReferenceType())
- return false;
- Ty = Ty->getPointeeType();
- if (Ty.getCVRQualifiers() != Qualifiers::Const)
- return false;
- const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- return RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace();
+ (getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ getDeclName().getCXXOverloadedOperator() == OO_Array_Delete) &&
+ Ctx.hasSameType(Ty, Ctx.getSizeType())) {
+ IsSizedDelete = true;
+ Consume();
+ }
+
+ // In C++17, the next parameter can be a 'std::align_val_t' for aligned
+ // new/delete.
+ if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull() && Ty->isAlignValT())
+ Consume();
+
+ // Finally, if this is not a sized delete, the final parameter can
+ // be a 'const std::nothrow_t&'.
+ if (!IsSizedDelete && !Ty.isNull() && Ty->isReferenceType()) {
+ Ty = Ty->getPointeeType();
+ if (Ty.getCVRQualifiers() != Qualifiers::Const)
+ return false;
+ const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+ if (RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace())
+ Consume();
+ }
+
+ return Params == FPT->getNumParams();
}
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
OpenPOWER on IntegriCloud