forked from OSchip/llvm-project
[OPENMP]Honor constantness of captured variables.
Fixes bug reported via Stackoverflow: https://stackoverflow.com/questions/64179168/clang-overload-resolution-failure-with-templates-and-openmp-collapse Need to honor constantness of private/target variables to make the code compilable. Differential Revision: https://reviews.llvm.org/D91644
This commit is contained in:
parent
06c192d454
commit
8f51dc4967
|
@ -17468,7 +17468,11 @@ bool Sema::tryCaptureVariable(
|
|||
if (IsTargetCap || IsOpenMPPrivateDecl == OMPC_private ||
|
||||
(IsGlobal && !IsGlobalCap)) {
|
||||
Nested = !IsTargetCap;
|
||||
bool HasConst = DeclRefType.isConstQualified();
|
||||
DeclRefType = DeclRefType.getUnqualifiedType();
|
||||
// Don't lose diagnostics about assignments to const.
|
||||
if (HasConst)
|
||||
DeclRefType.addConst();
|
||||
CaptureType = Context.getLValueReferenceType(DeclRefType);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
|
@ -95,7 +95,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
|
||||
#pragma omp distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
struct vector {
|
||||
vector() = default;
|
||||
int at(int) { return 0; }
|
||||
int at(int) const { return 1; }
|
||||
};
|
||||
|
||||
// CHECK: template <typename T> void test(const vector begin_vec) {
|
||||
// CHECK: #pragma omp parallel for collapse(2)
|
||||
// CHECK: for (int n = begin_vec.at(0); n < 0; n++) {
|
||||
// CHECK: for (int h = begin_vec.at(1); h < 1; h++) {
|
||||
// CHECK: ;
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: template<> void test<int>(const vector begin_vec) {
|
||||
// CHECK: #pragma omp parallel for collapse(2)
|
||||
// CHECK: for (int n = begin_vec.at(0); n < 0; n++) {
|
||||
// CHECK: for (int h = begin_vec.at(1); h < 1; h++) {
|
||||
// CHECK: ;
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
template <typename T>
|
||||
void test(const vector begin_vec) {
|
||||
#pragma omp parallel for collapse(2)
|
||||
for (int n = begin_vec.at(0); n < 0; n++) {
|
||||
for (int h = begin_vec.at(1); h < 1; h++) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
vector v;
|
||||
test<int>(v);
|
||||
}
|
||||
#endif
|
|
@ -37,8 +37,8 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
|
@ -108,7 +108,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}}
|
||||
#pragma omp teams distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -37,8 +37,8 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
|
@ -108,7 +108,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute parallel for firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}}
|
||||
#pragma omp teams distribute parallel for firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -38,8 +38,8 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
|
@ -109,7 +109,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute parallel for simd firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}}
|
||||
#pragma omp teams distribute parallel for simd firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
|
|
|
@ -39,8 +39,8 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
|
@ -110,7 +110,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute simd firstprivate (k, a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}}
|
||||
#pragma omp teams distribute simd firstprivate (k, a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
|
|
Loading…
Reference in New Issue