[cfe-dev] [Bug] Wrong Exception Handling : Destructor not called immediately

Richard Smith richard at metafoo.co.uk
Mon Apr 21 14:05:50 PDT 2014


On Mon, Apr 21, 2014 at 1:47 PM, John McCall <rjmccall at apple.com> wrote:

> On Apr 21, 2014, at 12:21 PM, suyog sarda <sardask01 at gmail.com> wrote:
>
> Ok. sorry for my silly question above. i tested the code for the question
> i had, and it seems that destructor of all temporaries
> as well as other objects created before the current line are being called
> when exception occurs, except the destructor of the
> outermost object.
>
> From the discussion in the link shared in the previous mail and the
> results of the test case, i conclude that for
> clang, outermost object *temp *of class *b *is not considered constructed
> until all the inner temporaries are destroyed.
>
> Since the outermost 'temp' is considered yet to be constructed fully, its
> destructor is not pushed in '*EHStack*'.
> As a result whenever exception occurs in the destructor of temporaries,
> the EHStack does not contain destructor of outermost
> object and hence its cleanup doesn't take place.
>
> Please correct me if i am wrong? Also, while debugging i came across,
> following piece of code,
>
> *void CodeGenFunction::EmitCXXTryStmt <http://clang.llvm.org/doxygen/classclang_1_1CodeGen_1_1CodeGenFunction.html#a079ab0affd32c3e7d992d8421776b732>(const CXXTryStmt <http://clang.llvm.org/doxygen/classclang_1_1CXXTryStmt.html> &S <http://clang.llvm.org/doxygen/AnalysisBasedWarnings_8cpp.html#a33dc45a03958a0bf07b5da2dec4db648>) {
>         EnterCXXTryStmt <http://clang.llvm.org/doxygen/classclang_1_1CodeGen_1_1CodeGenFunction.html#ae064b29757ae2b6085d4df62ea2df530>(S);
>         EmitStmt <http://clang.llvm.org/doxygen/classclang_1_1CodeGen_1_1CodeGenFunction.html#ab625dabfdcc8082335d64c4cbd009ef0>(S.getTryBlock <http://clang.llvm.org/doxygen/classclang_1_1CXXTryStmt.html#a0b14fc308d0e5f78e4f2bd425fc308da>());
>         ExitCXXTryStmt <http://clang.llvm.org/doxygen/classclang_1_1CodeGen_1_1CodeGenFunction.html#ac1f782050e59094db58fbbd1b9e3f8c1>(S);
>  }*
>
>
>
> which after several function calls in between leads me to below (for
> init-temp1.C test code) :
>
> *CodeGenFunction::emitAutoVarTypeCleanup*
> {
> .....
>
>
>
>
> *// Use an EH cleanup in array destructors iff the destructor itself   //
> is being pushed as an EH cleanup.  bool useEHCleanup = (cleanupKind &
> EHCleanup);  EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type,
> destroyer,                                     useEHCleanup);*
> }
>
> At this point the destructor is pushed to EHStack. When i traced the code
> for init-temp1.C, i hit the *EHStack.pushcleanup *function above*, *still
> the destructor of outermost object is not being called.
>
> Can someone please help me if i am looking at right place? If my analysis
> for clang is right - outermost object not considered created until
> innermost temporaries are destroyed - where should i look to correct this
> problem?
>
> If by design, clang doesn't consider outermost object to be created until
> inner temporaries are destroyed, would this be a resource leak (i don't
> think it is leak, as the object is yet to be constructed, hence no
> destruction required)?
>
> Your help would be highly appreciated.
>
>
>
> If the constructor has completed, the destructor needs to be called later.
>  IIRC, the problem that makes solving this so annoying is that, as soon as
> one temporary destructor terminates abnormally, the next thing to destroy
> is always the local variable (since it was constructed most recently), and
> only then proceeding to destroy the remainder of the temporaries.
>
> That is, if we’re creating local variable X, and we needed to construct
> temporaries A, B, and C to do that, then if C’s destructor throws, we need
> to destroy X, then B, then A; and if B’s destructor throws, we need to
> destroy X before A.
>
> This is not achievable with a simple stack mechanism.
>

Also of note is
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1634, which
will introduce a "full expression storage duration" for temporaries. Right
now, the destruction order is not wonderfully well-specified; under that
change, we'll need to clarify whether X is destroyed before the
temporaries, or whether full-expression storage duration objects are
destroyed before automatic storage duration objects in all cases (which
lets us use a simple stack).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140421/b377c54d/attachment.html>


More information about the cfe-dev mailing list