From 6a71f364f175a94a92cb26908b36d972734a611d Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 22 Aug 2017 17:54:52 +0000 Subject: [PATCH] [OPENMP] Fix for PR34014: OpenMP 4.5: Target construct in static method of class fails to map class static variable. If the global variable is captured and it has several redeclarations, sometimes it may lead to a compiler crash. Patch fixes this by working only with canonical declarations. llvm-svn: 311479 --- clang/lib/CodeGen/CGExpr.cpp | 1 + clang/lib/CodeGen/CGStmtOpenMP.cpp | 2 ++ clang/lib/CodeGen/CodeGenFunction.h | 2 ++ clang/lib/Sema/SemaExpr.cpp | 1 + clang/test/OpenMP/target_map_codegen.cpp | 18 ++++++++++++++++++ 5 files changed, 24 insertions(+) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0217efb9fb4f..93ca6011e169 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2300,6 +2300,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Check for captured variables. if (E->refersToEnclosingVariableOrCapture()) { + VD = VD->getCanonicalDecl(); if (auto *FD = LambdaCaptureFields.lookup(VD)) return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue); else if (CapturedStmtInfo) { diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 1b148828435b..4de88bc9d4e2 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -65,6 +65,8 @@ public: for (auto &C : CS->captures()) { if (C.capturesVariable() || C.capturesVariableByCopy()) { auto *VD = C.getCapturedVar(); + assert(VD == VD->getCanonicalDecl() && + "Canonical decl must be captured."); DeclRefExpr DRE(const_cast(VD), isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo && diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index c87e4d15c5e6..e334c315b8e4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -709,6 +709,7 @@ public: llvm::function_ref PrivateGen) { assert(PerformCleanup && "adding private to dead scope"); + LocalVD = LocalVD->getCanonicalDecl(); // Only save it once. if (SavedLocals.count(LocalVD)) return false; @@ -761,6 +762,7 @@ public: /// Checks if the global variable is captured in current function. bool isGlobalVarCaptured(const VarDecl *VD) const { + VD = VD->getCanonicalDecl(); return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5272dc3c95df..2a36a83daf6c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14200,6 +14200,7 @@ bool Sema::tryCaptureVariable( bool IsGlobal = !Var->hasLocalStorage(); if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedDecl(Var))) return true; + Var = Var->getCanonicalDecl(); // Walk up the stack to determine whether we can capture the variable, // performing the "simple" checks that don't depend on type. We stop when diff --git a/clang/test/OpenMP/target_map_codegen.cpp b/clang/test/OpenMP/target_map_codegen.cpp index 69e80bb9505b..820815c8c280 100644 --- a/clang/test/OpenMP/target_map_codegen.cpp +++ b/clang/test/OpenMP/target_map_codegen.cpp @@ -15,12 +15,30 @@ // RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 #ifdef CK1 +class B { +public: + static double VAR; + B() { + } + + static void modify(int &res) { +#pragma omp target map(tofrom \ + : res) + { + res = B::VAR; + } + } +}; +double B::VAR = 1.0; + // CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 // CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK1-LABEL: implicit_maps_integer void implicit_maps_integer (int a){ + // CK1: call void{{.*}}modify + B::modify(a); int i = a; // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})