https://github.com/akash-manna-sky updated https://github.com/llvm/llvm-project/pull/225604
>From ec4b4aea04588281488aa5b98f0020ef214835cc Mon Sep 17 00:00:00 2001 From: Akash Manna <[email protected]> Date: Wed, 23 Sep 2026 11:42:41 +0530 Subject: [PATCH 1/2] [clang][OpenMP] Use the list item location as point of instantiation in mapper lookup Implicit map clauses have no source location, and the "default" mapper lookup inherited that invalid location as the point of instantiation for any class template specialization ADL had to complete, which asserted in setPointOfInstantiation. Thread the mapped list item's location into buildUserDefinedMapperRef and use it for the ADL and derived-class checks, matching what the other default-mapper lookups already do. Fixes #154704 --- clang/docs/ReleaseNotes.md | 2 ++ clang/lib/Sema/SemaOpenMP.cpp | 28 ++++++++++++++++------------ clang/test/OpenMP/gh154704.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 clang/test/OpenMP/gh154704.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index f4a34a37aff52e..d62c61d04c43c7 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -547,6 +547,8 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when an `asm` label names the register for a global variable of incomplete type. (#GH219746) - Fixed an ICE hat occurred when using `__imag int/float` as lvalue in assignment. (#GH119498) - Fixed an assertion failure in `-Wsign-compare` when a negated or complemented vector of unsigned integers was compared against a signed constant. (#GH203575) +- 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) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2e4d9f2f82f0b7..8303ac7b922542 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 00000000000000..bd160a6ec52d0e --- /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}} + } +} >From f2509a6a0f60e6fd3b027d430f46524ea4820641 Mon Sep 17 00:00:00 2001 From: Akash Manna <[email protected]> Date: Wed, 23 Sep 2026 11:47:33 +0530 Subject: [PATCH 2/2] Reposition the release notes to avoid the conflicts --- clang/docs/ReleaseNotes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index d62c61d04c43c7..7afd1fef6083ed 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -542,13 +542,13 @@ 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) - Fixed an ICE hat occurred when using `__imag int/float` as lvalue in assignment. (#GH119498) - Fixed an assertion failure in `-Wsign-compare` when a negated or complemented vector of unsigned integers was compared against a signed constant. (#GH203575) -- 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) #### Bug Fixes to Compiler Builtins _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
