llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->154704

When a variable is implicitly mapped on `#pragma omp target`, Clang looks for a 
user-defined mapper for its type through ADL, and ADL may have to instantiate 
class template specializations named by the type's template arguments (for 
`std::map&lt;int, int&gt;` that's its allocator). Implicit map clauses carry no 
source location by design, and the "default" mapper id was stamped with that 
empty location, so the instantiation was recorded with an invalid point of 
instantiation and `setPointOfInstantiation` asserted.

`buildUserDefinedMapperRef` now takes the location of the mapped list item and 
uses it for the ADL and the derived-class checks, which is what the other 
default-mapper lookups in `SemaOpenMP.cpp` already did. Diagnostics about the 
mapper id and the mapper reference itself keep the mapper-id location, so 
explicit `mapper(id)` behavior is unchanged. The instantiation is now 
attributed to the mapped variable inside the region, which is also where the 
"in instantiation requested here" note points.


---
Full diff: https://github.com/llvm/llvm-project/pull/225604.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+2) 
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+16-12) 
- (added) clang/test/OpenMP/gh154704.cpp (+33) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index f4a34a37aff52..7afd1fef6083e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -542,6 +542,8 @@ features cannot lower the translation-unit ABI level;
 - Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma 
could cause pragma parsing issues when inside of a member function. (#GH214195)
 - Fixed a bug where preprocessor directives following comments were not 
correctly recognized when using -C. (#GH48361)
 - Fixed a crash when declaring a member template within a local class inside 
an OpenMP region. (#GH216052)
+- Fixed an assertion failure when a variable implicitly mapped by an OpenMP 
`target` directive has a class type
+  (such as `std::map`) whose mapper lookup instantiates a class template 
specialization. (#GH154704)
 - Fixed a bug where repeated #imports of modular headers in non-modular 
compilation were translated to #pragma clang module import. (#GH216924)
 - Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare 
variant` is followed by another OpenMP declarative directive containing a 
qualified identifier. (#GH217204)
 - Fixed a crash when an `asm` label names the register for a global variable 
of incomplete type. (#GH219746)
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2e4d9f2f82f0b..8303ac7b92254 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6042,7 +6042,8 @@ static ExprResult buildUserDefinedMapperRef(Sema 
&SemaRef, Scope *S,
                                             CXXScopeSpec &MapperIdScopeSpec,
                                             const DeclarationNameInfo 
&MapperId,
                                             QualType Type,
-                                            Expr *UnresolvedMapper);
+                                            Expr *UnresolvedMapper,
+                                            SourceLocation ItemLoc);
 
 /// Perform DFS through the structure/class data members trying to find
 /// member(s) with user-defined 'default' mapper and generate implicit map
@@ -6114,7 +6115,7 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy 
*Stack,
           DefaultMapperId.setLoc(E->getExprLoc());
           ExprResult ER = buildUserDefinedMapperRef(
               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
-              BaseType, /*UnresolvedMapper=*/nullptr);
+              BaseType, /*UnresolvedMapper=*/nullptr, E->getExprLoc());
           if (ER.isInvalid())
             continue;
           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
@@ -23565,12 +23566,15 @@ static bool checkMapConflicts(
 }
 
 // Look up the user-defined mapper given the mapper name and mapped type, and
-// build a reference to it.
+// build a reference to it. \a ItemLoc is the location of the mapped list item;
+// it is used as the point of instantiation since \a MapperId has no location
+// for implicit map clauses.
 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
                                             CXXScopeSpec &MapperIdScopeSpec,
                                             const DeclarationNameInfo 
&MapperId,
                                             QualType Type,
-                                            Expr *UnresolvedMapper) {
+                                            Expr *UnresolvedMapper,
+                                            SourceLocation ItemLoc) {
   if (MapperIdScopeSpec.isInvalid())
     return ExprError();
   // Get the actual type for the array type.
@@ -23636,7 +23640,7 @@ static ExprResult buildUserDefinedMapperRef(Sema 
&SemaRef, Scope *S,
   }
   // Perform argument dependent lookup.
   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
-    argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
+    argumentDependentLookup(SemaRef, MapperId, ItemLoc, Type, Lookups);
   // Return the first user-defined mapper with the desired type.
   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
@@ -23649,9 +23653,9 @@ static ExprResult buildUserDefinedMapperRef(Sema 
&SemaRef, Scope *S,
   // Find the first user-defined mapper with a type derived from the desired
   // type.
   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
-          Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
+          Lookups, [&SemaRef, Type, ItemLoc](ValueDecl *D) -> ValueDecl * {
             if (!D->isInvalidDecl() &&
-                SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
+                SemaRef.IsDerivedFrom(ItemLoc, Type, D->getType()) &&
                 !Type.isMoreQualifiedThan(D->getType(),
                                           SemaRef.getASTContext()))
               return D;
@@ -23659,11 +23663,11 @@ static ExprResult buildUserDefinedMapperRef(Sema 
&SemaRef, Scope *S,
           })) {
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                        /*DetectVirtual=*/false);
-    if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
+    if (SemaRef.IsDerivedFrom(ItemLoc, Type, VD->getType(), Paths)) {
       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
               VD->getType().getUnqualifiedType()))) {
         if (SemaRef.CheckBaseClassAccess(
-                Loc, VD->getType(), Type, Paths.front(),
+                ItemLoc, VD->getType(), Type, Paths.front(),
                 /*DiagID=*/0) != Sema::AR_inaccessible) {
           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
         }
@@ -23969,7 +23973,7 @@ static void checkMappableExpressionList(
       // Try to find the associated user-defined mapper.
       ExprResult ER = buildUserDefinedMapperRef(
           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
-          VE->getType().getCanonicalType(), UnresolvedMapper);
+          VE->getType().getCanonicalType(), UnresolvedMapper, ELoc);
       if (ER.isInvalid())
         continue;
       MVLI.UDMapperList.push_back(ER.get());
@@ -24013,7 +24017,7 @@ static void checkMappableExpressionList(
       // Try to find the associated user-defined mapper.
       ExprResult ER = buildUserDefinedMapperRef(
           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
-          VE->getType().getCanonicalType(), UnresolvedMapper);
+          VE->getType().getCanonicalType(), UnresolvedMapper, ELoc);
       if (ER.isInvalid())
         continue;
       MVLI.UDMapperList.push_back(ER.get());
@@ -24215,7 +24219,7 @@ static void checkMappableExpressionList(
     // Try to find the associated user-defined mapper.
     ExprResult ER = buildUserDefinedMapperRef(
         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
-        Type.getCanonicalType(), UnresolvedMapper);
+        Type.getCanonicalType(), UnresolvedMapper, ELoc);
     if (ER.isInvalid())
       continue;
 
diff --git a/clang/test/OpenMP/gh154704.cpp b/clang/test/OpenMP/gh154704.cpp
new file mode 100644
index 0000000000000..bd160a6ec52d0
--- /dev/null
+++ b/clang/test/OpenMP/gh154704.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -verify -fopenmp -fsyntax-only %s
+
+template <typename T> struct Less {};
+
+template <typename K, typename V, typename C = Less<K>> struct Map {
+  V &operator[](const K &);
+};
+
+void no_crash() {
+  int keys[42], data[42];
+  Map<int, int> map;
+
+#pragma omp target
+  {
+    for (int i = 0; i < 42; ++i)
+      map[keys[i]] = data[i];
+  }
+}
+
+template <typename T> struct Fails {
+  typename T::type t; // expected-error {{type 'int' cannot be used prior to 
'::' because it has no members}}
+};
+
+template <typename T, typename U = Fails<T>> struct Holder {};
+
+void point_of_instantiation() {
+  Holder<int> h;
+
+#pragma omp target
+  {
+    (void)&h; // expected-note {{in instantiation of template class 
'Fails<int>' requested here}}
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/225604
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to