Skip to content

Commit 631a486

Browse files
committed
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
1 parent 778cf08 commit 631a486

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,14 +1330,17 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
13301330
// C++0x [expr.new]p17:
13311331
// If the new expression creates an array of objects of class type,
13321332
// access and ambiguity control are done for the destructor.
1333-
if (ArraySize && AllocType->isRecordType() && !AllocType->isDependentType()) {
1334-
if (CXXDestructorDecl *dtor = LookupDestructor(
1335-
cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl()))) {
1336-
MarkFunctionReferenced(StartLoc, dtor);
1337-
CheckDestructorAccess(StartLoc, dtor,
1338-
PDiag(diag::err_access_dtor)
1339-
<< Context.getBaseElementType(AllocType));
1340-
DiagnoseUseOfDecl(dtor, StartLoc);
1333+
QualType BaseAllocType = Context.getBaseElementType(AllocType);
1334+
if (ArraySize && !BaseAllocType->isDependentType()) {
1335+
if (const RecordType *BaseRecordType = BaseAllocType->getAs<RecordType>()) {
1336+
if (CXXDestructorDecl *dtor = LookupDestructor(
1337+
cast<CXXRecordDecl>(BaseRecordType->getDecl()))) {
1338+
MarkFunctionReferenced(StartLoc, dtor);
1339+
CheckDestructorAccess(StartLoc, dtor,
1340+
PDiag(diag::err_access_dtor)
1341+
<< BaseAllocType);
1342+
DiagnoseUseOfDecl(dtor, StartLoc);
1343+
}
13411344
}
13421345
}
13431346

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -emit-llvm-only %s
2+
3+
// this used to crash due to templ<int>'s dtor not being marked as used by the
4+
// new expression in func()
5+
struct non_trivial {
6+
non_trivial() {}
7+
~non_trivial() {}
8+
};
9+
template < typename T > class templ {
10+
non_trivial n;
11+
};
12+
void func() {
13+
new templ<int>[1][1];
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
class ctor {
4+
ctor(); // expected-note{{implicitly declared private here}}
5+
};
6+
7+
class dtor {
8+
~dtor(); // expected-note 3 {{implicitly declared private here}}
9+
};
10+
11+
void test() {
12+
new ctor[0]; // expected-error{{calling a private constructor of class 'ctor'}}
13+
new dtor[0]; // expected-error{{calling a private destructor of class 'dtor'}}
14+
new dtor[3]; // expected-error{{calling a private destructor of class 'dtor'}}
15+
new dtor[3][3]; // expected-error{{calling a private destructor of class 'dtor'}}
16+
}

0 commit comments

Comments
 (0)