From: David Blaikie Date: Sat, 10 Mar 2012 23:40:02 +0000 (+0000) Subject: Fix crash & accepts-invalid for array of arrays of user defined type. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=426d6ca163e20187761aa55a67797dac51508d0d;p=clang Fix crash & accepts-invalid for array of arrays of user defined type. Test case/other help by Richard Smith. Code review by John McCall. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152519 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8eeb09ebbd..b56d3ebfb2 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/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(AllocType->getAs()->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()) { + if (CXXDestructorDecl *dtor = LookupDestructor( + cast(BaseRecordType->getDecl()))) { + MarkFunctionReferenced(StartLoc, dtor); + CheckDestructorAccess(StartLoc, dtor, + PDiag(diag::err_access_dtor) + << BaseAllocType); + DiagnoseUseOfDecl(dtor, StartLoc); + } } } diff --git a/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp b/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp new file mode 100644 index 0000000000..27b915e959 --- /dev/null +++ b/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'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[1][1]; +} diff --git a/test/CXX/expr/expr.unary/expr.new/p17.cpp b/test/CXX/expr/expr.unary/expr.new/p17.cpp new file mode 100644 index 0000000000..0d108eb6a8 --- /dev/null +++ b/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'}} +}