]> granicus.if.org Git - clang/commit
Don't assume cleanup emission preserves dominance in expr evaluation
authorReid Kleckner <rnk@google.com>
Mon, 6 Mar 2017 22:18:34 +0000 (22:18 +0000)
committerReid Kleckner <rnk@google.com>
Mon, 6 Mar 2017 22:18:34 +0000 (22:18 +0000)
commita53bfab123cecb584f6b6a58f6315de656358e92
tree3f942ed2213170fcf4788e26d49e23cf4ab4bbaf
parentba524690b91049ad6491d1639d500eb787607c1d
Don't assume cleanup emission preserves dominance in expr evaluation

Summary:
Because of the existence branches out of GNU statement expressions, it
is possible that emitting cleanups for a full expression may cause the
new insertion point to not be dominated by the result of the inner
expression. Consider this example:

  struct Foo { Foo(); ~Foo(); int x; };
  int g(Foo, int);
  int f(bool cond) {
    int n = g(Foo(), ({ if (cond) return 0; 42; }));
    return n;
  }

Before this change, result of the call to 'g' did not dominate its use
in the store to 'n'. The early return exit from the statement expression
branches to a shared cleanup block, which ends in a switch between the
fallthrough destination (the assignment to 'n') or the function exit
block.

This change solves the problem by spilling and reloading expression
evaluation results when any of the active cleanups have branches.

I audited the other call sites of enterFullExpression, and they don't
appear to keep and Values live across the site of the cleanup, except in
ARC code. I wasn't able to create a test case for ARC that exhibits this
problem, though.

Reviewers: rjmccall, rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D30590

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297084 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/CGCleanup.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/stmtexpr.cpp