IBM Support

IJ15509: DESTRUCTOR IS NOT BEING CALLED WITH RETURN IN TRY BLOCK

Subscribe

You can track all active APARs for this component.

 

APAR status

  • Closed as program error.

Error description

  • If a return is used in a nested try block, then the destructors
    of objects are on the stack will not be called. This is shown
    with the testcase below:
    
    ===== COMPILE COMMAND:
    xlclang++ test.cpp
    
    ===== TESTCASE:
    $ cat test.cpp
    #include <iostream>
    
    using namespace std;
    class Line {
       public:
          void setLength( double len );
          double getLength( void );
          Line();   // This is the constructor declaration
          ~Line();  // This is the destructor: declaration
    
       private:
          double length;
    };
    
    // Member functions definitions including constructor
    Line::Line(void) {
       cout << "Object is being created" << endl;
    }
    Line::~Line(void) {
       cout << "Object is being deleted" << endl;
    }
    void Line::setLength( double len ) {
       length = len;
    }
    double Line::getLength( void ) {
       return length;
    }
    
    
    void  try_1()
    {
       Line line1;
       try {
               line1.setLength(96.0);
           return;}
           catch ( ... ) {
           cerr << "Catch 2"; }
    }
    void  try_nested()
    {
       Line line1;
       {
         {
           try {
               line1.setLength(96.0);
           return;}
           catch ( ... ) {
               cerr << "Catch 2";
           }
         }
       }
    }
    
    
    void  try_try()
    {
       Line line2;
       try {
               line2.setLength(96.0);
            try {
    
               line2.setLength(196.0);
    //           line2.~Line();
                return;
                   }
           catch ( ... ) {
           cerr << "Catch 1" ;}
           }
           catch ( ... ) {
           cerr << "Catch 2"; }
    
    
    }
    
    
    // Main function for the program
    int main() {
    
       cout << "               " <<endl;
       cout << "               " <<endl;
       cout << " BEGIN: single try with return" <<endl;
       cout << "-------->  Expectartion: Constructor/Destructor is
    called " <<endl;
    
       try_1();
       cout << " END:   single try with return" <<endl;
    ////////////
       cout << "             --------   " <<endl;
       cout << "               " <<endl;
       cout << "               " <<endl;
       cout << " BEGIN: nested  try with return" <<endl;
       cout << "-------->  Expectartion: Constructor/Destructor is
    called " <<endl;
    
       try_nested();
    
       cout << " END:   nested try with return" <<endl;
    ///////////
       cout << "               " <<endl;
       cout << "               " <<endl;
       cout << " BEGIN: try in a try with return" <<endl;
       cout << "-------->  Expectartion: Constructor/Destructor is
    called " <<endl;
    
       try_try();
    
       cout << " END:  try in a try with return" <<endl;
       // cout << "Length of line : " << line.getLength()+1 <<endl;
       return 0;
    }
    
    
    $
    
    
    ===== ACTUAL OUTPUT:
    $ ./a.out
    
    
    BEGIN: single try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    Object is being deleted
    END:   single try with return
                 --------
    
    
    BEGIN: nested  try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    END:   nested try with return
    
    
    BEGIN: try in a try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    END:  try in a try with return
    $
    
    ===== EXPECTED OUTPUT:
    $ ./a.out
    
    
    BEGIN: single try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    Object is being deleted
    END:   single try with return
                 --------
    
    
    BEGIN: nested  try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    Object is being deleted
    END:   nested try with return
    
    
    BEGIN: try in a try with return
    -------->  Expectartion: Constructor/Destructor is called
    Object is being created
    Object is being deleted
    END:  try in a try with return
    $
    

Local fix

  • N/A
    

Problem summary

  • USERS AFFECTED:
    Clients using return statements in a try-catch block may be
    affected by this issue.
    
    PROBLEM DESCRIPTION:
    The return call was not running all destructors to the
    outermost block causing an inconsistent state.
    

Problem conclusion

  • The return call now calls all the appropriate destructors.
    

Temporary fix

Comments

APAR Information

  • APAR number

    IJ15509

  • Reported component name

    XL C/C++ FOR AI

  • Reported component ID

    5725C7200

  • Reported release

    G10

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt / Xsystem

  • Submitted date

    2019-04-17

  • Closed date

    2019-06-12

  • Last modified date

    2019-06-12

  • APAR is sysrouted FROM one or more of the following:

  • APAR is sysrouted TO one or more of the following:

    LI80776

Fix information

  • Fixed component name

    XL C/C++ FOR AI

  • Fixed component ID

    5725C7200

Applicable component levels

[{"Business Unit":{"code":"BU048","label":"IBM Software"},"Product":{"code":"SSGH3R","label":"XL C\/C++ for AIX"},"Component":"","ARM Category":[],"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"G10","Edition":"","Line of Business":{"code":"LOB73","label":"Power TPS"}}]

Document Information

Modified date:
21 August 2024