diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 33 | ||||
| -rw-r--r-- | clang/test/SemaCXX/new-delete-predefined-decl.cpp | 18 | ||||
| -rw-r--r-- | clang/test/SemaCXX/new-delete.cpp | 7 |
3 files changed, 46 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7671995d609..850308e1477 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -630,14 +630,19 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. - if (FunctionDecl *Fn = - dyn_cast<FunctionDecl>((*Alloc)->getUnderlyingDecl())) { - AddOverloadCandidate(Fn, Alloc.getAccess(), Args, NumArgs, Candidates, - /*SuppressUserConversions=*/false); + + if (FunctionTemplateDecl *FnTemplate = + dyn_cast<FunctionTemplateDecl>((*Alloc)->getUnderlyingDecl())) { + AddTemplateOverloadCandidate(FnTemplate, Alloc.getAccess(), + /*ExplicitTemplateArgs=*/0, Args, NumArgs, + Candidates, + /*SuppressUserConversions=*/false); continue; - } - - // FIXME: Handle function templates + } + + FunctionDecl *Fn = cast<FunctionDecl>((*Alloc)->getUnderlyingDecl()); + AddOverloadCandidate(Fn, Alloc.getAccess(), Args, NumArgs, Candidates, + /*SuppressUserConversions=*/false); } // Do the resolution. @@ -768,12 +773,16 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, DeclContext::lookup_iterator Alloc, AllocEnd; for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name); Alloc != AllocEnd; ++Alloc) { - // FIXME: Do we need to check for default arguments here? - FunctionDecl *Func = cast<FunctionDecl>(*Alloc); - if (Func->getNumParams() == 1 && + // Only look at non-template functions, as it is the predefined, + // non-templated allocation function we are trying to declare here. + if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) { + QualType InitialParamType = Context.getCanonicalType( - Func->getParamDecl(0)->getType().getUnqualifiedType()) == Argument) - return; + Func->getParamDecl(0)->getType().getUnqualifiedType()); + // FIXME: Do we need to check for default arguments here? + if (Func->getNumParams() == 1 && InitialParamType == Argument) + return; + } } } diff --git a/clang/test/SemaCXX/new-delete-predefined-decl.cpp b/clang/test/SemaCXX/new-delete-predefined-decl.cpp new file mode 100644 index 00000000000..6234b740a47 --- /dev/null +++ b/clang/test/SemaCXX/new-delete-predefined-decl.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -DTEMPLATE_OVERLOAD -fsyntax-only -verify %s + +#include <stddef.h> + +// Note that each test must be run separately so it can be the first operator +// new declaration in the file. + +#if defined(TEMPLATE_OVERLOAD) +// Don't crash on global template operator new overloads. +template<typename T> void* operator new(size_t, T); +void test_template_overload() { + (void)new(0) double; +} +#endif + +void test_predefined() { + (void)new double; +} diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index b058fc13d96..6f895553431 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -216,3 +216,10 @@ static void* f(void* g) { return new (g) X13(); } + +namespace PR5918 { // Look for template operator new overloads. + struct S { template<typename T> static void* operator new(size_t, T); }; + void test() { + (void)new(0) S; + } +} |

