[PATCH] D153273: CPP-4465 Rework support for CFGScopeBegin, CFGScopeEnd, CFGLifetime elements

Tomasz KamiƄski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 19 06:51:31 PDT 2023


tomasz-kaminski-sonarsource created this revision.
Herald added a reviewer: NoQ.
Herald added a project: All.
tomasz-kaminski-sonarsource requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch reworks generation for the `CFGScopeBegin`, `CFGScopeEnd`,
and `CFGLiftimeEnd`, in a way that they are now compatible with each
other and `CFGAutomaticObjDtor`. All of the above elements are now
generated by a single code path, that conditionally inserts elements if
they are requested.

In addition, the handling of `goto` statements is improved.
The `goto` statement may leave multiple scopes (and trigger destruction
and lifetime end for the affected variables) and enter multiple scopes,
for example:

  C++
  {
    int s1;
    {
      int s2;
      goto label; // leaves s1, s2, and enters t1 t1
    }
  }
  {
    int t1;
    {
      int t2;
  label:
    }
  }

This is performed by first determining the shared parent scope of the
source and destination. And then emitting elements for exiting each
scope between the source and the parent, and entering each scope
between the parent and destination. All such elements are appended
to the source block, as one label may be reached from multiple scopes.

Finally, the approach for handling backward jumps is changed. When
connecting a source block to a destination block that requires the
insertion of additional elements, we put this element into a new block,
which is then linked between the source and the destination block.
For example:

  C++
  {
    int t;
  label:
    // Destination block referred to as 'DB'
  }
  {
    // Source block referred to as 'SB'
    Obj s;
    goto label;
  }

The jump between `SB` with terminator `T: goto` and `DB` should be
coupled with the following CFG elements:

  CFGAutomaticObjDtor(s)
  CFGLifetimeEnd(s)
  CFGScopeEnd(s)
  CFGScopeBegin(t)

To handle such situations, we create a new link (`LB`) that is linked as
the predecessor of `DB`, to which we transfer the terminator (`goto`
statement) of `SB`. Then `LB` is handled in the same manner as the
source block in the case of forward jumps.
This produces CFG that looks like this:

  SB -> LB (T: goto) -> DB

Finally, the resulting block is linked as the successor of `SB`. Such an
approach uses existing handling of the `noreturn` destructors.
As a reminder, for each destructor of an automatic object that is
marked as `noreturn`, a new `noreturn` block (marked `NBn`) is
created, at the destructor is inserted at the end of it.
To illustrate, given two `noreturn` destructors, we will have:

  SB -> NB1 (noreturn)
  NB2 (noreturn)
  LB (T:goto) -> DB


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153273

Files:
  clang/include/clang/Analysis/CFG.h
  clang/lib/Analysis/CFG.cpp
  clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
  clang/test/Analysis/lifetime-cfg-output.cpp
  clang/test/Analysis/no-exit-cfg.c
  clang/test/Analysis/nonreturn-destructors-cfg-output.cpp
  clang/test/Analysis/scopes-cfg-output.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153273.532638.patch
Type: text/x-patch
Size: 42701 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230619/dcedd931/attachment-0001.bin>


More information about the cfe-commits mailing list