diff options
| author | David Blaikie <dblaikie@gmail.com> | 2012-03-10 23:40:02 +0000 |
|---|---|---|
| committer | David Blaikie <dblaikie@gmail.com> | 2012-03-10 23:40:02 +0000 |
| commit | 631a486e6a0d7c6c4cfb957064489a462e700c80 (patch) | |
| tree | 5367280931d6e2517131c376eca08ea8546c878e | |
| parent | 778cf08746009f1815d0f0ed3f2234b6faff1957 (diff) | |
| download | bcm5719-llvm-631a486e6a0d7c6c4cfb957064489a462e700c80.tar.gz bcm5719-llvm-631a486e6a0d7c6c4cfb957064489a462e700c80.zip | |
Fix crash & accepts-invalid for array of arrays of user defined type.
Test case/other help by Richard Smith.
Code review by John McCall.
llvm-svn: 152519
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 19 | ||||
| -rw-r--r-- | clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CXX/expr/expr.unary/expr.new/p17.cpp | 16 |
3 files changed, 41 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8eeb09ebbd3..b56d3ebfb28 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1330,14 +1330,17 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, // C++0x [expr.new]p17: // If the new expression creates an array of objects of class type, // access and ambiguity control are done for the destructor. - if (ArraySize && AllocType->isRecordType() && !AllocType->isDependentType()) { - if (CXXDestructorDecl *dtor = LookupDestructor( - cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl()))) { - MarkFunctionReferenced(StartLoc, dtor); - CheckDestructorAccess(StartLoc, dtor, - PDiag(diag::err_access_dtor) - << Context.getBaseElementType(AllocType)); - DiagnoseUseOfDecl(dtor, StartLoc); + QualType BaseAllocType = Context.getBaseElementType(AllocType); + if (ArraySize && !BaseAllocType->isDependentType()) { + if (const RecordType *BaseRecordType = BaseAllocType->getAs<RecordType>()) { + if (CXXDestructorDecl *dtor = LookupDestructor( + cast<CXXRecordDecl>(BaseRecordType->getDecl()))) { + MarkFunctionReferenced(StartLoc, dtor); + CheckDestructorAccess(StartLoc, dtor, + PDiag(diag::err_access_dtor) + << BaseAllocType); + DiagnoseUseOfDecl(dtor, StartLoc); + } } } diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp new file mode 100644 index 00000000000..27b915e9596 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm-only %s + +// this used to crash due to templ<int>'s dtor not being marked as used by the +// new expression in func() +struct non_trivial { + non_trivial() {} + ~non_trivial() {} +}; +template < typename T > class templ { + non_trivial n; +}; +void func() { + new templ<int>[1][1]; +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp new file mode 100644 index 00000000000..0d108eb6a89 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class ctor { + ctor(); // expected-note{{implicitly declared private here}} +}; + +class dtor { + ~dtor(); // expected-note 3 {{implicitly declared private here}} +}; + +void test() { + new ctor[0]; // expected-error{{calling a private constructor of class 'ctor'}} + new dtor[0]; // expected-error{{calling a private destructor of class 'dtor'}} + new dtor[3]; // expected-error{{calling a private destructor of class 'dtor'}} + new dtor[3][3]; // expected-error{{calling a private destructor of class 'dtor'}} +} |

