diff options
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/new-delete.cpp | 18 |
2 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e03c5721c6c..6d8c9146541 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1046,7 +1046,14 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, llvm::SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches; - if (NumPlaceArgs > 0) { + // Whether we're looking for a placement operator delete is dictated + // by whether we selected a placement operator new, not by whether + // we had explicit placement arguments. This matters for things like + // struct A { void *operator new(size_t, int = 0); ... }; + // A *a = new A() + bool isPlacementNew = (NumPlaceArgs > 0 || OperatorNew->param_size() != 1); + + if (isPlacementNew) { // C++ [expr.new]p20: // A declaration of a placement deallocation function matches the // declaration of a placement allocation function if it has the diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index ef20aee009c..f6129d19841 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -354,3 +354,21 @@ namespace DeleteParam { void operator delete(void* const); }; } + +// <rdar://problem/8427878> +// Test that the correct 'operator delete' is selected to pair with +// the unexpected placement 'operator new'. +namespace PairedDelete { + template <class T> struct A { + A(); + void *operator new(size_t s, double d = 0); + void operator delete(void *p, double d); + void operator delete(void *p) { + T::dealloc(p); + } + }; + + A<int> *test() { + return new A<int>(); + } +} |