summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp33
-rw-r--r--clang/test/SemaCXX/new-delete-predefined-decl.cpp18
-rw-r--r--clang/test/SemaCXX/new-delete.cpp7
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;
+ }
+}
OpenPOWER on IntegriCloud