Skip to content
This repository has been archived by the owner on Jun 20, 2019. It is now read-only.

Bug 227: Fix spurious warning of function returning address of local variable. #217

Merged
merged 1 commit into from Jun 6, 2016

Commits on Jun 5, 2016

  1. Bug 227: Fix spurious warning of function returning address of local …

    …variable.
    
    First, this does a small refactor/clean-up of codegen for passing
    parameters that have been lowered to a COMPOUND_EXPR, spliting the value
    from the rest of the construction/destruction expression if possible.
    
    A similar rewrite is done in build_expr, where the following rewrites
    are done for simple expressions:
    
    ```
      cast(T)(e1, e2) => (e1, cast(T)e2)
      &(e1, e2) => (e1, &e2)
      *(e1, e2) => (e1, *e2)
    ```
    
    Moving the COMPOUND_EXPR up to the top allows us to have more control on
    when inserting dtors into the expression.
    
    Where before we may have done (a contrived example):
    
    ```
      SAVE<tmp = __ctor(), tmp>, __dtor(&tmp), SAVE<tmp = __ctor(), tmp>;
    ```
    
    Rewriting `&(e1, e2)` into `(e1, &e2)` means we can inspect the right
    hand side for any side effects, if there are none pressent, then we can
    bypass saving the comma expression, eliding any artificial temporaries
    being created by the code generator/optimizer.
    
    ```
      tmp = __ctor(), __dtor(&tmp), tmp;
    ```
    
    Finally, for fixing bug 227, the code generation for running destructors
    on return expressions has been separated from normal expressions,
    because we should be returning the result directly, rather than
    returning the temporary created to evaluate the expression before
    calling its destructors.
    
    ```
      return &(try
        {
          SAVE<*(SAVE<*(SAVE<&(tmp = __ctor(), tmp)>), {}>,
               __cpctor(this, SAVE<*(SAVE<&(tmp = __ctor(), tmp)>), {}>))>;
        }
      finally
        {
          __dtor(&tmp);
        }, SAVE<*(SAVE<*(SAVE<&(tmp = __ctor(), tmp)>), {}>,
                __cpctor(this, SAVE<*(SAVE<&(tmp = __ctor(), tmp)>), {}>))>);
    
    ```
    
    With the first refactor in passing parameters, we remove one layer of
    temporaries being created in the call to `__cpctor()`.
    
    ```
      return &(try
        {
          SAVE<*(*(SAVE<&(tmp = __ctor(), tmp)>), __cpctor(this, {}))>;
        }
      finally
        {
          __dtor(&tmp);
        }, SAVE<*(*(SAVE<&(tmp = __ctor(), tmp)>), __cpctor(this, {}))>);
    ```
    
    With the second refactor, another layer is removed, as the construction
    of the temporary is not needed when dereferencing the result of
    `__cpctor()`.
    
    ```
      return &(try
        {
          *(SAVE<&(tmp = __ctor(), tmp)>);, SAVE<*__cpctor(this, {})>;;
        }
      finally
        {
          __dtor(&tmp);
        }, SAVE<*__cpctor(this, {})>;);
    ```
    
    Finally, moving the return expression into `build_return_dtor`, the
    return is inserted directory into the try block, removing the bogus
    temporary that was causing the warning in the first place.
    
    ```
      try
        {
          *(SAVE<&(tmp = __ctor(), tmp)>);
          return __cpctor(this, {});
        }
      finally
        {
          __dtor(&tmp);
        }
    ```
    ibuclaw committed Jun 5, 2016
    Copy the full SHA
    491f194 View commit details
    Browse the repository at this point in the history