Author: abataev
Date: Tue Mar 19 13:33:44 2019
New Revision: 356513

URL: http://llvm.org/viewvc/llvm-project?rev=356513&view=rev
Log:
[OPENMP]Warn if the different allocator is used for the variable.

If the allocator was specified for the variable and next one is found
with the different allocator, the warning is emitted, and the allocator
is ignored.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp
    cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp
    cfe/trunk/test/OpenMP/allocate_codegen.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=356513&r1=356512&r2=356513&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 19 13:33:44 
2019
@@ -9146,6 +9146,12 @@ def err_omp_expected_predefined_allocato
   "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', "
   "'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', "
   "'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'">;
+def warn_omp_used_different_allocator : Warning<
+  "allocate directive specifies %select{default|'%1'}0 allocator while "
+  "previously used %select{default|'%3'}2">,
+  InGroup<OpenMPClauses>;
+def note_omp_previous_allocator : Note<
+  "previous allocator is specified here">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=356513&r1=356512&r2=356513&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Mar 19 13:33:44 2019
@@ -2216,6 +2216,61 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAl
     if (isa<ParmVarDecl>(VD))
       continue;
 
+    // If the used several times in the allocate directive, the same allocator
+    // must be used.
+    if (VD->hasAttr<OMPAllocateDeclAttr>()) {
+      const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+      const Expr *PrevAllocator = A->getAllocator();
+      bool AllocatorsMatch = false;
+      if (Allocator && PrevAllocator) {
+        const Expr *AE = Allocator->IgnoreParenImpCasts();
+        const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
+        llvm::FoldingSetNodeID AEId, PAEId;
+        AE->Profile(AEId, Context, /*Canonical=*/true);
+        PAE->Profile(PAEId, Context, /*Canonical=*/true);
+        AllocatorsMatch = AEId == PAEId;
+      } else if (!Allocator && !PrevAllocator) {
+        AllocatorsMatch = true;
+      } else {
+        const Expr *AE = Allocator ? Allocator : PrevAllocator;
+        // In this case the specified allocator must be the default one.
+        AE = AE->IgnoreParenImpCasts();
+        if (const auto *DRE = dyn_cast<DeclRefExpr>(AE)) {
+          DeclarationName DN = DRE->getDecl()->getDeclName();
+          AllocatorsMatch =
+              DN.isIdentifier() &&
+              DN.getAsIdentifierInfo()->isStr("omp_default_mem_alloc");
+        }
+      }
+      if (!AllocatorsMatch) {
+        SmallString<256> AllocatorBuffer;
+        llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
+        if (Allocator)
+          Allocator->printPretty(AllocatorStream, nullptr, 
getPrintingPolicy());
+        SmallString<256> PrevAllocatorBuffer;
+        llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
+        if (PrevAllocator)
+          PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
+                                     getPrintingPolicy());
+
+        SourceLocation AllocatorLoc =
+            Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
+        SourceRange AllocatorRange =
+            Allocator ? Allocator->getSourceRange() : 
RefExpr->getSourceRange();
+        SourceLocation PrevAllocatorLoc =
+            PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
+        SourceRange PrevAllocatorRange =
+            PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
+        Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
+            << (Allocator ? 1 : 0) << AllocatorStream.str()
+            << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
+            << AllocatorRange;
+        Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
+            << PrevAllocatorRange;
+        continue;
+      }
+    }
+
     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
     // If a list item has a static storage type, the allocator expression in 
the
     // allocator clause must be a constant expression that evaluates to one of
@@ -2254,11 +2309,17 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAl
     }
 
     Vars.push_back(RefExpr);
-    Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
-                                                  DE->getSourceRange());
-    VD->addAttr(A);
-    if (ASTMutationListener *ML = Context.getASTMutationListener())
-      ML->DeclarationMarkedOpenMPAllocate(VD, A);
+    if ((!Allocator || (Allocator && !Allocator->isTypeDependent() &&
+                        !Allocator->isValueDependent() &&
+                        !Allocator->isInstantiationDependent() &&
+                        !Allocator->containsUnexpandedParameterPack())) &&
+        !VD->hasAttr<OMPAllocateDeclAttr>()) {
+      Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
+                                                    DE->getSourceRange());
+      VD->addAttr(A);
+      if (ASTMutationListener *ML = Context.getASTMutationListener())
+        ML->DeclarationMarkedOpenMPAllocate(VD, A);
+    }
   }
   if (Vars.empty())
     return nullptr;

Modified: cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp?rev=356513&r1=356512&r2=356513&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp Tue Mar 19 13:33:44 
2019
@@ -38,15 +38,16 @@ struct St1{
 // CHECK-NEXT: #pragma omp allocate(St1::b) 
allocator(omp_default_mem_alloc){{$}}
 } d;
 
-int a, b;
+int a, b, c;
 // CHECK: int a;
 // CHECK: int b;
+// CHECK: int c;
 #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
-#pragma omp allocate(a) allocator(omp_const_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
 // CHECK-NEXT: #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
-// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_const_mem_alloc)
-#pragma omp allocate(d, b) allocator(omp_high_bw_mem_alloc)
-// CHECK-NEXT: #pragma omp allocate(d,b) allocator(omp_high_bw_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(c, d) allocator(omp_high_bw_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(c,d) allocator(omp_high_bw_mem_alloc)
 
 template <class T>
 struct ST {

Modified: cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp?rev=356513&r1=356512&r2=356513&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp Tue Mar 19 13:33:44 
2019
@@ -14,16 +14,27 @@ int sss;
 #pragma omp allocate(sss) allocator(0,sss)  // expected-error {{expected ')'}} 
expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} 
expected-note {{to match this '('}}
 #pragma omp allocate(sss) allocator(sss)  // expected-error 
{{omp_allocator_handle_t type not found; include <omp.h>}}
 
-typedef void *omp_allocator_handle_t;
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
 
 struct St1{
  int a;
  static int b;
-#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 
'omp_allocator_handle_t' (aka 'void *') with an expression of incompatible type 
'int'}}
+#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 
'omp_allocator_handle_t' (aka 'void **') with an expression of incompatible 
type 'int'}} expected-note {{previous allocator is specified here}}
+#pragma omp allocate(b)
+#pragma omp allocate(b) allocator(omp_thread_mem_alloc) // expected-warning 
{{allocate directive specifies 'omp_thread_mem_alloc' allocator while 
previously used default}}
 } d; // expected-note 2 {{'d' defined here}}
 
 // expected-error@+1 {{expected one of the predefined allocators for the 
variables with the static storage: 'omp_default_mem_alloc', 
'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 
'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 
'omp_thread_mem_alloc'}}
 #pragma omp allocate(d) allocator(nullptr)
-extern void *allocator;
+extern void **allocator;
 // expected-error@+1 {{expected one of the predefined allocators for the 
variables with the static storage: 'omp_default_mem_alloc', 
'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 
'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 
'omp_thread_mem_alloc'}}
 #pragma omp allocate(d) allocator(allocator)
+#pragma omp allocate(d) allocator(omp_thread_mem_alloc) // expected-note 
{{previous allocator is specified here}}
+#pragma omp allocate(d) // expected-warning {{allocate directive specifies 
default allocator while previously used 'omp_thread_mem_alloc'}}
+
+int c;
+#pragma omp allocate(c) allocator(omp_thread_mem_alloc) // expected-note 
{{previous allocator is specified here}}
+#pragma omp allocate(c) allocator(omp_high_bw_mem_alloc) // expected-warning 
{{allocate directive specifies 'omp_high_bw_mem_alloc' allocator while 
previously used 'omp_thread_mem_alloc'}}
+

Modified: cfe/trunk/test/OpenMP/allocate_codegen.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/allocate_codegen.cpp?rev=356513&r1=356512&r2=356513&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/allocate_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/allocate_codegen.cpp Tue Mar 19 13:33:44 2019
@@ -37,10 +37,10 @@ struct St1{
 #pragma omp allocate(b) allocator(omp_default_mem_alloc)
 } d;
 
-int a, b;
+int a, b, c;
 #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
-#pragma omp allocate(a) allocator(omp_const_mem_alloc)
-#pragma omp allocate(d, b) allocator(omp_high_bw_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(d, c) allocator(omp_high_bw_mem_alloc)
 
 template <class T>
 struct ST {


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to