Don't generate any code for an explicit call to a trivial destructor.

Now that parsing, semantic analysis, and (I think) code generation of
pseudo-destructor expressions and explicit destructor calls works,
update the example-dynarray.cpp test to destroy the objects it
allocates and update the test to actually compile + link.
The code seems correct, but the Clang-compiled version dies with a
malloc error. Time to debug!

llvm-svn: 81025
This commit is contained in:
Douglas Gregor 2009-09-04 19:04:08 +00:00
parent 35337557af
commit d94105a1c2
5 changed files with 23 additions and 9 deletions

View File

@ -178,6 +178,11 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
assert(MD->isInstance() &&
"Trying to emit a member call expr on a static method!");
// A call to a trivial destructor requires no code generation.
if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD))
if (Destructor->isTrivial())
return RValue::get(0);
const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
CallArgList Args;
@ -218,6 +223,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
llvm::Value *Callee;
if (MD->isVirtual() && !ME->hasQualifier())
Callee = BuildVirtualCall(MD, This, Ty);
else if (const CXXDestructorDecl *Destructor
= dyn_cast<CXXDestructorDecl>(MD))
Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
else
Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);

View File

@ -812,7 +812,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
// If there was no specific requested type, just convert it now.
if (!Ty)
Ty = getTypes().ConvertType(GD.getDecl()->getType());
return GetOrCreateLLVMFunction(getMangledName(GD.getDecl()), Ty, GD);
return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD);
}
/// CreateRuntimeFunction - Create a new runtime function with the specified

View File

@ -2634,7 +2634,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
}
void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
CXXDestructorDecl *Destructor) {
CXXDestructorDecl *Destructor) {
assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
"DefineImplicitDestructor - call it for implicit default dtor");

View File

@ -1,4 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
// RUN: clang %s -o %t
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
@ -24,6 +24,9 @@ public:
}
~dynarray() {
for (unsigned I = 0, N = size(); I != N; ++I)
Start[I].~T();
free(Start);
}
@ -33,7 +36,9 @@ public:
for (unsigned I = 0, N = other.size(); I != N; ++I)
new (NewStart + I) T(other[I]);
// FIXME: destroy everything in Start
for (unsigned I = 0, N = size(); I != N; ++I)
Start[I].~T();
free(Start);
Start = NewStart;
Last = End = NewStart + other.size();
@ -46,8 +51,8 @@ public:
void push_back(const T& value);
void pop_back() {
// FIXME: destruct old value
--Last;
Last->~T();
}
T& operator[](unsigned Idx) {
@ -99,7 +104,8 @@ void dynarray<T>::push_back(const T& value) {
for (unsigned I = 0; I != Size; ++I)
new (NewStart + I) T(Start[I]);
// FIXME: destruct old values
for (unsigned I = 0, N = size(); I != N; ++I)
Start[I].~T();
free(Start);
Start = NewStart;

View File

@ -574,9 +574,9 @@ welcome!</p>
<tr>
<td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.4 [expr.pseudo]</td>
<td class="complete"></td>
<td class="medium"></td>
<td class="medium"></td>
<td></td>
<td class="complete"></td>
<td class="complete"></td>
<td class="complete"></td>
<td></td>
</tr>
<tr>