summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-02-03 11:02:14 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-02-03 11:02:14 +0000
commit935384217de60628b301a19dad4cf8d95fb570ee (patch)
tree774a2e24709967660532216f173a7a68f4e4c1e9
parent7ceffab64d26ddcb312d2e8b990b9e8ac40159ab (diff)
downloadbcm5719-llvm-935384217de60628b301a19dad4cf8d95fb570ee.tar.gz
bcm5719-llvm-935384217de60628b301a19dad4cf8d95fb570ee.zip
Teach the allocation function overload handling to deal with templates, and
prevent a crash on templates when looking for an existing declaration of the predefined global operators. This fixes PR5918. Added an easy test case for the overload handling, but testing the crash is a bit trickier. Created a new test that can use multiple runs with a define to trigger which test case is used so we can test this type of issue. llvm-svn: 95220
-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