]> granicus.if.org Git - clang/commitdiff
[OPENMP][BLOCKS]Fix PR38923: reference to a global variable is captured
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 20 Aug 2018 16:00:22 +0000 (16:00 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 20 Aug 2018 16:00:22 +0000 (16:00 +0000)
by a block.

Added checks for capturing of the variable in the block when trying to
emit correct address for the variable with the reference type. This
extra check allows correctly identify the variables that are not
captured in the block context.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340181 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/block-byref.cpp [new file with mode: 0644]

index 605c01d52b2b06296bd3393cb2c821bc8f5cb43a..b74937e9ca13310147c1285fe7e8cc91338436a9 100644 (file)
@@ -2437,6 +2437,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
     // A DeclRefExpr for a reference initialized by a constant expression can
     // appear without being odr-used. Directly emit the constant initializer.
     const Expr *Init = VD->getAnyInitializer(VD);
+    const auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl);
     if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
         VD->isUsableInConstantExpressions(getContext()) &&
         VD->checkInitIsICE() &&
@@ -2446,7 +2447,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
             (LocalDeclMap.count(VD->getCanonicalDecl()) ||
              CapturedStmtInfo->lookup(VD->getCanonicalDecl()))) ||
            LambdaCaptureFields.lookup(VD->getCanonicalDecl()) ||
-           isa<BlockDecl>(CurCodeDecl)))) {
+           (BD && BD->capturesVariable(VD))))) {
       llvm::Constant *Val =
         ConstantEmitter(*this).emitAbstract(E->getLocation(),
                                             *VD->evaluateValue(),
diff --git a/test/CodeGenCXX/block-byref.cpp b/test/CodeGenCXX/block-byref.cpp
new file mode 100644 (file)
index 0000000..1cb86a5
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s
+// REQUIRES: x86-registered-target
+
+// CHECK: @b = global i32 0,
+
+// CHECK: define {{.*}}void @{{.*}}test{{.*}}_block_invoke(
+// CHECK: store i32 2, i32* @b,
+// CHECK: ret void
+
+int b;
+
+void test() {
+  int &a = b;
+  ^{ a = 2; };
+}