[PATCH] D47096: CodeGen: block capture shouldn't ICE
JF Bastien via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri May 18 21:07:41 PDT 2018
jfb updated this revision to Diff 147647.
jfb added a comment.
- Follow John's suggestion.
Repository:
rC Clang
https://reviews.llvm.org/D47096
Files:
lib/CodeGen/CGDecl.cpp
test/CodeGen/block-capture.cpp
Index: test/CodeGen/block-capture.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/block-capture.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -fblocks -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %struct.__block_byref_baz = type { i8*, %struct.__block_byref_baz*, i32, i32, i32 }
+// CHECK: [[baz:%[0-9a-z_]*]] = alloca %struct.__block_byref_baz
+// CHECK: [[bazref:%[0-9a-z_\.]*]] = getelementptr inbounds %struct.__block_byref_baz, %struct.__block_byref_baz* [[baz]], i32 0, i32 1
+// CHECK: store %struct.__block_byref_baz* [[baz]], %struct.__block_byref_baz** [[bazref]]
+// CHECK: [[disposable:%[0-9a-z_]*]] = bitcast %struct.__block_byref_baz* [[baz]] to i8*
+// CHECK: call void @_Block_object_dispose(i8* [[disposable]]
+
+int main() {
+ __block int baz = [&]() { return 0; }();
+ return 0;
+}
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -1244,37 +1244,50 @@
return emission;
}
+static bool isCapturedBy(const VarDecl &, const Expr *);
+
+/// Determines whether the given __block variable is potentially
+/// captured by the given statement.
+static bool isCapturedBy(const VarDecl &Var, const Stmt *S) {
+ if (const Expr *E = dyn_cast<Expr>(S))
+ return isCapturedBy(Var, E);
+ for (const Stmt *SubStmt : S->children())
+ if (isCapturedBy(Var, SubStmt))
+ return true;
+ return false;
+}
+
/// Determines whether the given __block variable is potentially
/// captured by the given expression.
-static bool isCapturedBy(const VarDecl &var, const Expr *e) {
+static bool isCapturedBy(const VarDecl &Var, const Expr *E) {
// Skip the most common kinds of expressions that make
// hierarchy-walking expensive.
- e = e->IgnoreParenCasts();
+ E = E->IgnoreParenCasts();
- if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
- const BlockDecl *block = be->getBlockDecl();
- for (const auto &I : block->captures()) {
- if (I.getVariable() == &var)
+ if (const BlockExpr *BE = dyn_cast<BlockExpr>(E)) {
+ const BlockDecl *Block = BE->getBlockDecl();
+ for (const auto &I : Block->captures()) {
+ if (I.getVariable() == &Var)
return true;
}
// No need to walk into the subexpressions.
return false;
}
- if (const StmtExpr *SE = dyn_cast<StmtExpr>(e)) {
+ if (const StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
const CompoundStmt *CS = SE->getSubStmt();
for (const auto *BI : CS->body())
- if (const auto *E = dyn_cast<Expr>(BI)) {
- if (isCapturedBy(var, E))
- return true;
+ if (const auto *BIE = dyn_cast<Expr>(BI)) {
+ if (isCapturedBy(Var, BIE))
+ return true;
}
else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
// special case declarations
for (const auto *I : DS->decls()) {
if (const auto *VD = dyn_cast<VarDecl>((I))) {
const Expr *Init = VD->getInit();
- if (Init && isCapturedBy(var, Init))
+ if (Init && isCapturedBy(Var, Init))
return true;
}
}
@@ -1286,8 +1299,8 @@
return false;
}
- for (const Stmt *SubStmt : e->children())
- if (isCapturedBy(var, cast<Expr>(SubStmt)))
+ for (const Stmt *SubStmt : E->children())
+ if (isCapturedBy(Var, SubStmt))
return true;
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47096.147647.patch
Type: text/x-patch
Size: 3486 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180519/d514e4d7/attachment.bin>
More information about the cfe-commits
mailing list