]> granicus.if.org Git - clang/commitdiff
[OpenMP] diagnose assign to firstprivate const, patch by Joel E. Denny
authorAlexey Bataev <a.bataev@hotmail.com>
Fri, 10 Nov 2017 15:39:50 +0000 (15:39 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Fri, 10 Nov 2017 15:39:50 +0000 (15:39 +0000)
Summary:
[OpenMP] diagnose assign to firstprivate const

Clang does not diagnose assignments to const variables declared
firstprivate.  Furthermore, codegen is broken such that, at run time,
such assignments simply have no effect.  For example, the following
prints 0 not 1:

int main() {
  const int i = 0;
  #pragma omp parallel firstprivate(i)
  { i=1; printf("%d\n", i); }
  return 0;
}

This commit makes these assignments a compile error, which is
consistent with other OpenMP compilers I've tried (pgcc 17.4-0, gcc
6.3.0).

Reviewers: ABataev

Reviewed By: ABataev

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D39859

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

lib/Sema/SemaExpr.cpp
test/OpenMP/parallel_firstprivate_messages.cpp

index d5a7bc31a81de60231d198b682e42075b8dda6cd..f895e0fa1f53b059e035864173b952346b057d07 100644 (file)
@@ -14352,8 +14352,13 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,
   bool ByRef = true;
   // Using an LValue reference type is consistent with Lambdas (see below).
   if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP) {
-    if (S.IsOpenMPCapturedDecl(Var))
+    if (S.IsOpenMPCapturedDecl(Var)) {
+      bool HasConst = DeclRefType.isConstQualified();
       DeclRefType = DeclRefType.getUnqualifiedType();
+      // Don't lose diagnostics about assignments to const.
+      if (HasConst)
+        DeclRefType.addConst();
+    }
     ByRef = S.IsOpenMPCapturedByRef(Var, RSI->OpenMPLevel);
   }
 
index fc0eb4c7d3586b836ce18dc80facf9b520c15f25..b2cb4ff131ef12b58ea468ccac4b129883588d98 100644 (file)
@@ -56,7 +56,7 @@ using A::x;
 }
 
 int main(int argc, char **argv) {
-  const int d = 5;
+  const int d = 5; // expected-note {{variable 'd' declared const here}}
   const int da[5] = { 0 };
   S4 e(4);
   S5 g(5);
@@ -72,6 +72,8 @@ int main(int argc, char **argv) {
   #pragma omp parallel firstprivate (argc)
   #pragma omp parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
   #pragma omp parallel firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  #pragma omp parallel firstprivate (d)
+    d = 5; // expected-error {{cannot assign to variable 'd' with const-qualified type}}
   #pragma omp parallel firstprivate (argv[1]) // expected-error {{expected variable name}}
   #pragma omp parallel firstprivate(ba)
   #pragma omp parallel firstprivate(ca)