[clang] 8f51dc4 - [OPENMP]Honor constantness of captured variables.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 20 11:12:28 PST 2020


Author: Alexey Bataev
Date: 2020-11-20T11:11:47-08:00
New Revision: 8f51dc49673c494cc1d118979b596288e938af13

URL: https://github.com/llvm/llvm-project/commit/8f51dc49673c494cc1d118979b596288e938af13
DIFF: https://github.com/llvm/llvm-project/commit/8f51dc49673c494cc1d118979b596288e938af13.diff

LOG: [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

Added: 
    clang/test/OpenMP/openmp_capture_const_var_ast_print.cpp

Modified: 
    clang/lib/Sema/SemaExpr.cpp
    clang/test/OpenMP/distribute_firstprivate_messages.cpp
    clang/test/OpenMP/teams_distribute_firstprivate_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
    clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7a8124fadfd7..60a685bfdf15 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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;
           }

diff  --git a/clang/test/OpenMP/distribute_firstprivate_messages.cpp b/clang/test/OpenMP/distribute_firstprivate_messages.cpp
index 346d1a834a86..25a5e9db0eb8 100644
--- a/clang/test/OpenMP/distribute_firstprivate_messages.cpp
+++ b/clang/test/OpenMP/distribute_firstprivate_messages.cpp
@@ -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

diff  --git a/clang/test/OpenMP/openmp_capture_const_var_ast_print.cpp b/clang/test/OpenMP/openmp_capture_const_var_ast_print.cpp
new file mode 100644
index 000000000000..4d4b0b00cbaf
--- /dev/null
+++ b/clang/test/OpenMP/openmp_capture_const_var_ast_print.cpp
@@ -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

diff  --git a/clang/test/OpenMP/teams_distribute_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_firstprivate_messages.cpp
index b845a23d847d..c65e1f409695 100644
--- a/clang/test/OpenMP/teams_distribute_firstprivate_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_firstprivate_messages.cpp
@@ -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

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
index 0509391b313e..fa323b6e7319 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -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

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
index 9d8137b1962b..9b117c8b397d 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -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

diff  --git a/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
index c8a95c2f1553..855d045e02b9 100644
--- a/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
@@ -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


        


More information about the cfe-commits mailing list