[OPENMP]Fix error emission for dependent expressions in iterators for depend clauses.

Need to postpone analysis for addressable lvalue in a depend clause with
iterators, otherwise the incorrect error message is emitted.

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

GitOrigin-RevId: a9036f2eb42d2311d84198868e9e8ff060c79a95
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 22ae5f5..b9b0005 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -18636,22 +18636,19 @@
         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
             !RefExpr->isInstantiationDependent() &&
             !RefExpr->containsUnexpandedParameterPack() &&
-            (OMPDependTFound &&
-             DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
+            (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
+             (OMPDependTFound &&
+              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
-              << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
-              << RefExpr->getSourceRange();
+              << (LangOpts.OpenMP >= 50 ? 1 : 0)
+              << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
           continue;
         }
 
         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
-        if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
-            (ASE && !ASE->getBase()->isTypeDependent() &&
-             !ASE->getBase()
-                  ->getType()
-                  .getNonReferenceType()
-                  ->isPointerType() &&
-             !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
+        if (ASE && !ASE->getBase()->isTypeDependent() &&
+            !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
+            !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
               << (LangOpts.OpenMP >= 50 ? 1 : 0)
               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp
index 4b28067..8f3994f 100644
--- a/test/OpenMP/target_enter_data_depend_messages.cpp
+++ b/test/OpenMP/target_enter_data_depend_messages.cpp
@@ -46,7 +46,7 @@
   foo();
   #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target enter data map(to : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
+#pragma omp target enter data map(to : i) depend(in : argv[1][1] = '2')
   foo();
 #pragma omp target enter data map(to : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
   foo();
diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp
index a1bcdb0..2bb64c4 100644
--- a/test/OpenMP/target_exit_data_depend_messages.cpp
+++ b/test/OpenMP/target_exit_data_depend_messages.cpp
@@ -46,7 +46,7 @@
   foo();
   #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
   foo();
-#pragma omp target exit data map(from : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
+#pragma omp target exit data map(from : i) depend(in : argv[1][1] = '2')
   foo();
 #pragma omp target exit data map(from : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
   foo();
diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp
index b218d4d..949b122 100644
--- a/test/OpenMP/target_update_depend_messages.cpp
+++ b/test/OpenMP/target_update_depend_messages.cpp
@@ -39,7 +39,7 @@
 #pragma omp target update to(z) depend(out:)    // expected-error {{expected expression}}
 #pragma omp target update to(z) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
 #pragma omp target update to(z) depend(out : S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target update to(z) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
+#pragma omp target update to(z) depend(in : argv[1][1] = '2')
 #pragma omp target update to(z) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
 #pragma omp target update to(z) depend(in : argv[0])
 #pragma omp target update to(z) depend(in:) // expected-error {{expected expression}}
diff --git a/test/OpenMP/task_depend_template_call_ast_print.cpp b/test/OpenMP/task_depend_template_call_ast_print.cpp
new file mode 100644
index 0000000..3456f7b
--- /dev/null
+++ b/test/OpenMP/task_depend_template_call_ast_print.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+template <typename> class vector {
+public:
+  int &at(long);
+};
+
+// CHECK:      template <typename T> void foo(int n) {
+// CHECK-NEXT:   vector<T> v;
+// CHECK-NEXT:   vector<int> iv1;
+// CHECK-NEXT: #pragma omp task depend(iterator(int i = 0:n), in : v.at(i),iv1.at(i))
+// CHECK-NEXT:     ;
+// CHECK-NEXT: }
+
+template <typename T> void foo(int n) {
+  vector<T> v;
+  vector<int> iv1;
+#pragma omp task depend(iterator(i = 0 : n), in : v.at(i), iv1.at(i))
+  ;
+}
+#endif