[cfe-dev] Strange CFG for `try' blocks

Ilya Palachev via cfe-dev cfe-dev at lists.llvm.org
Mon Jun 26 02:42:00 PDT 2017


Hi everyone,

Recently we've noticed a strange behaviour in CFG construction for 
function try blocks. Clang test suite has a test case 
SemaCXX/return-noreturn.cpp with functions functionTryBlock{1,2,3}, and 
at least for functionTryBlock2 control flow graph looks a bit strange:

$ .../clang -cc1 -nostdsysteminc 
.../llvm/tools/clang/test/SemaCXX/return-noreturn.cpp -fsyntax-only 
-fcxx-exceptions -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code 
-Wno-covered-switch-default -analyze -analyzer-checker debug.DumpCFG 
2>&1 | grep functionTryBlock2 -A 19

    int functionTryBlock2(int s)
      [B3 (ENTRY)]
        Succs (1): B0

      [B1]
        T: try ...
        Succs (1): B2

      [B2]
       catch (...):
        1: catch (...) {
    [B2.3]}
        2: 0
        3: return [B2.2];
        Preds (1): B1
        Succs (1): B0

      [B0 (EXIT)]
        Preds (2): B2 B3

The strange place here is in the fact that block [B3] goes directly to 
[B0], leaving the block [B1] non-visited. Moreover, for the below three 
code examples the generated CFG looks the same:

============ 1 =============

int foo();

int functionTryBlock2(int s) try {
   s += foo();
} catch (...) {
   return s;
}

============ 2 =============

int foo();

int functionTryBlock2(int s) {
   try {
     s += foo();
   } catch (...) {
     return s;
   }
}

============ 3 =============

int foo();

int functionTryBlock2(int s) {
   s += foo();
   try {
   } catch (...) {
     return s;
   }
}

Is it a bug? It seems that `catch' blocks can be stayed without any 
predecessors, since they are visited not by `control flow', but by the 
exception. But why `try' blocks are not correctly included into CFG? And 
how should the correct CFG look like?

--
Best regards,
Ilya Palachev



More information about the cfe-dev mailing list