[llvm-bugs] [Bug 11645] CFG for destructors in '||'/'&&' lacks precision

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Aug 21 11:43:32 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=11645

Artem Dergachev <noqnoqneo at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED

--- Comment #51 from Artem Dergachev <noqnoqneo at gmail.com> ---
We're doing pretty well here, i guess the CFG was fixed by Manuel Klimek in
2014.

I attached the current CFG.svg for easier reading.

The CFG contains all three temporary destructors and one automatic destructor.
There's an extra correlated branch that controls conditional execution of ~B()
which makes the CFG look like a triple-diamond instead of a double-diamond. The
analyzer understands such branching it by remembering which temporaries were
created in a special path-sensitive state trait.

Additionally, i made sure that copy elision is marked up in the CFG: the
construct-expression on [B5.2] contains a forward reference to the future
actual constructor on [B5.8], alongside with heads-up on future bind-temporary
at [B5.5] and materialize-temporary at [B5.7]. Other constructors are not
elidable, so they only have forward references to bind/materialize temporary
(for A(x) and B(y)) and to the variable declaration (for 'C b'). The analyzer
was taught to make use of this information.

There are other problems of this sort that were not addressed, eg. GNU *binary*
?: operator is broken, but && and || seem fine.

Additionally, complexity of the CFG seems to grow linearly, and every temporary
destructor appears in the CFG exactly once; i didn't look deeply into this, but
it seems to be the case. Automatic destructor for 'C b' in our example will
appear twice (depending on which branch of the if-statement is taken), but this
doesn't seem to be exploitable. I'm attaching a CFG-chained-destructors.svg in
which the initializer for 'C b' is replaced with (A(1) && A(2)) || (A(3) &&
A(4)) || (A(5) && A(6)) || (A(7) && A(8)).

==================

Raw dump of the current CFG for easier comparing:

int test(int x, int y)
 [B8 (ENTRY)]
   Succs (1): B7

 [B1]
   1: [B5.9].~C() (Implicit destructor)
   2: bar
   3: [B1.2] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))
   4: [B1.3]()
   5: return [B1.4];
   Preds (1): B3
   Succs (1): B0

 [B2]
   1: foo
   2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))
   3: [B2.2]()
   4: return [B2.3];
   5: [B5.9].~C() (Implicit destructor)
   Preds (1): B3
   Succs (1): B0

 [B3]
   1: ~A() (Temporary object destructor)
   2: b
   3: [B3.2].operator bool
   4: [B3.2]
   5: [B3.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
   T: if [B3.5]
   Preds (2): B4 B5
   Succs (2): B2 B1

 [B4]
   1: ~B() (Temporary object destructor)
   Preds (1): B5
   Succs (1): B3

 [B5]
   1: [B7.9] || [B6.9]
   2: [B5.1] (ImplicitCastExpr, IntegralCast, int)
   3: [B5.2] (CXXConstructExpr, [B5.5], [B5.7], [B5.8], class C)
   4: [B5.3] (ImplicitCastExpr, ConstructorConversion, class C)
   5: [B5.4] (BindTemporary)
   6: [B5.5] (ImplicitCastExpr, NoOp, const class C)
   7: [B5.6]
   8: [B5.7] (CXXConstructExpr, [B5.9], class C)
   9: C b = A(x) || B(y);
  10: ~C() (Temporary object destructor)
   T: (Temp Dtor) [B6.4]
   Preds (2): B6 B7
   Succs (2): B4 B3

 [B6]
   1: y
   2: [B6.1] (ImplicitCastExpr, LValueToRValue, int)
   3: [B6.2] (CXXConstructExpr, [B6.4], [B6.6], class B)
   4: [B6.3] (BindTemporary)
   5: B([B6.4]) (CXXFunctionalCastExpr, ConstructorConversion, class B)
   6: [B6.5]
   7: [B6.6].operator bool
   8: [B6.6]
   9: [B6.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
   Preds (1): B7
   Succs (1): B5

 [B7]
   1: x
   2: [B7.1] (ImplicitCastExpr, LValueToRValue, int)
   3: [B7.2] (CXXConstructExpr, [B7.4], [B7.6], class A)
   4: [B7.3] (BindTemporary)
   5: A([B7.4]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
   6: [B7.5]
   7: [B7.6].operator bool
   8: [B7.6]
   9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
   T: [B7.9] || ...
   Preds (1): B8
   Succs (2): B5 B6

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180821/2a8a3f2a/attachment.html>


More information about the llvm-bugs mailing list