aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-07-13[Clang][P1061] Fix template arguments in local classes (#121225)Jason Rice1-1/+5
In the development of P1061 (Structured Bindings Introduce a Patch), I found this bug in the template instantiation of a local class. The issue is caused by the instantiation of the original template and not the partially instantiated template. In the example (sans the fix) the instantiation uses the first template parameter from the previous instantiation and not the current one so the error hits an assertion when it is expecting an NTTP. If they were both types then it might gladly accept the type from the wrong template which is kind of scary. In the test, the reference to `i` is substituted with a placeholder AST object that represents the resolved value when instantiating `g`. However, since the old template is used, the instantiation sees an AST object that only contains the template argument index in the context of instantiating the lambda which has a type template parameter (ie auto). I question if we should use `getTemplateInstantiationPattern` at all here. Other errors involving local classes in nested templates could also be caused by the misuse of this function (because it gets the uninstantiated template).
2025-07-10[Clang] Fix the template argument collection after CWG2369 (#147894)Younan Zhang1-17/+17
Since the function template isn't instantiated before constraint checking, we'll not be able to find the outer template arguments through function specialization when evaluating the inner constraint that is nested within a larger constraint expression. The only practical solution is to get them back through the code synthesis context, which also allows us to eliminate an overload of getTemplateInstantiationArgs. No release note because it's a regression on trunk. Fixes https://github.com/llvm/llvm-project/issues/147772
2025-07-08[Clang] Do not mark ambiguous specialization invalid. (#147275)Corentin Jabot1-1/+0
When a specialization was ambiguous, we would mark it as invalid, even if the specialization occured in an immediate context. This would subsequently lead to scenarios where invalid specialization produced no diagnostics, causing crashes during codegen. Fixes #51866
2025-06-02[Clang] Reapply CWG2369 "Ordering between constraints and substitution" ↵Younan Zhang1-11/+98
(#122423) The previous approach broke code generation for the MS ABI due to an unintended code path during constraint substitution. This time we address the issue by inspecting the evaluation contexts and thereby avoiding that code path. This reapplies 96eced624 (#102857).
2025-05-25[Sema] Remove unused includes (NFC) (#141419)Kazu Hirata1-1/+0
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-05-23[Clang] Fix the access checking for non-aggregates in default arguments ↵Younan Zhang1-7/+7
(#141207) We check the accessibility of constructors when initializing a default argument whose type is not an aggregate. Make sure the check is performed within the correct DeclContext. Otherwise, it will be delayed until the end of the declaration, at which point the context is mismatched. Fixes #62444 Fixes https://github.com/llvm/llvm-project/issues/83608
2025-05-09[Clang][NFC] Adding note on details that are not immediately obvious (#138349)Shafik Yaghmour1-0/+3
This code was flagged by static analysis. It was a false positive but the reason why this code is valid is subtle and folks refactoring this code in the future could easily miss it.
2025-05-05[Clang] Minimal support for availability attributes on partial ↵cor3ntin1-1/+17
specializations (#138426) There are some limitations. Because we only know which partial specialization to refer to when instantiating, and because we can't instantiate the class before we require a complete type, we can only use the partial specialization once we have a complete class. Similarly, because we don't know if a class is ever going to be complete, we always warn on availability of the primary. Therefore, we only warn for the partial specialization if we did not warn on the primary. I considered alternatives to address that second limitation: - Delay warnings to the end of the TU - Tracking where each availability attribute originally comes from. However, both of these have drawbacks, and the use case is probably less motivated than wanting to deprecate the use of a specific specialization. Fixes #44496
2025-05-01[clang] Add scoped enum support to `StreamingDiagnostic` (#138089)Vlad Serebrennikov1-3/+2
This patch adds templated `operator<<` for diagnostics that pass scoped enums, saving people from `llvm::to_underlying()` clutter on the side of emitting the diagnostic. This eliminates 80 out of 220 usages of `llvm::to_underlying()` in Clang. I also backported `std::is_scoped_enum_v` from C++23.
2025-04-17Reapply "[Clang] Fix dependent local class instantiation bugs" (#135914)Younan Zhang1-3/+0
This reapplies #134038 Since the last patch, this fixes a null pointer dereference where the TSI of the destructor wasn't properly propagated into the DeclarationNameInfo. We now construct a LocInfoType for dependent cases, as done elsewhere in getDestructorName, such that GetTypeFromParser can correctly obtain the TSI. --- This patch fixes two long-standing bugs that prevent Clang from instantiating local class members inside a dependent context. These bugs were introduced in commits https://github.com/llvm/llvm-project/commit/21eb1af469c3257606aec2270d544e0e8ecf77b2 and https://github.com/llvm/llvm-project/commit/919df9d75ac2a721a8072327c803f34486884571. https://github.com/llvm/llvm-project/commit/21eb1af469c3257606aec2270d544e0e8ecf77b2 introduced a concept called eligible methods such that it did an attempt to skip past ineligible method instantiation when instantiating class members. Unfortunately, this broke the instantiation chain for local classes - getTemplateInstantiationPattern() would fail to find the correct definition pattern if the class was defined within a partially transformed dependent context. https://github.com/llvm/llvm-project/commit/919df9d75ac2a721a8072327c803f34486884571 introduced a separate issue by incorrectly copying the DeclarationNameInfo during function definition instantiation from the template pattern, even though that DNI might contain a transformed TypeSourceInfo. Since that TSI was already updated when the declaration was instantiated, this led to inconsistencies. As a result, the final instantiated function could lose track of the transformed declarations, hence we crash: https://compiler-explorer.com/z/vjvoG76Tf. This PR corrects them by 1. Removing the bypass logic for method instantiation. The eligible flag is independent of instantiation and can be updated properly afterward, so skipping instantiation is unnecessary. 2. Carefully handling TypeSourceInfo by creating a new instance that preserves the pattern's source location while using the already transformed type.
2025-04-15Revert "[Clang] Fix dependent local class instantiation bugs" (#135870)Matheus Izvekov1-0/+3
Reverts llvm/llvm-project#134038 This crashes clang as reported here: https://github.com/llvm/llvm-project/pull/134038#issuecomment-2807092646
2025-04-15[Clang] Fix dependent local class instantiation bugs (#134038)Younan Zhang1-3/+0
This patch fixes two long-standing bugs that prevent Clang from instantiating local class members inside a dependent context. These bugs were introduced in commits 21eb1af469c3 and 919df9d75a. 21eb1af469c3 introduced a concept called eligible methods such that it did an attempt to skip past ineligible method instantiation when instantiating class members. Unfortunately, this broke the instantiation chain for local classes - getTemplateInstantiationPattern() would fail to find the correct definition pattern if the class was defined within a partially transformed dependent context. 919df9d75a introduced a separate issue by incorrectly copying the DeclarationNameInfo during function definition instantiation from the template pattern, even though that DNI might contain a transformed TypeSourceInfo. Since that TSI was already updated when the declaration was instantiated, this led to inconsistencies. As a result, the final instantiated function could lose track of the transformed declarations, hence we crash: https://compiler-explorer.com/z/vjvoG76Tf. This PR corrects them by 1. Removing the bypass logic for method instantiation. The eligible flag is independent of instantiation and can be updated properly afterward, so skipping instantiation is unnecessary. 2. Carefully handling TypeSourceInfo by creating a new instance that preserves the pattern's source location while using the already transformed type. Fixes https://github.com/llvm/llvm-project/issues/59734 Fixes https://github.com/llvm/llvm-project/issues/132208
2025-04-07[clang] fix partial ordering of NTTP packs (#134461)Matheus Izvekov1-4/+4
This fixes partial ordering of pack expansions of NTTPs, by procedding with the check using the pattern of the NTTP through the rules of the non-pack case. This also unifies almost all of the different versions of FinishTemplateArgumentDeduction (except the function template case). This makes sure they all follow the rules consistently, instantiating the parameters and comparing those with the argument. Fixes #132562
2025-04-03[clang] NFC: introduce UnsignedOrNone as a replacement for ↵Matheus Izvekov1-49/+51
std::optional<unsigned> (#134142) This introduces a new class 'UnsignedOrNone', which models a lite version of `std::optional<unsigned>`, but has the same size as 'unsigned'. This replaces most uses of `std::optional<unsigned>`, and similar schemes utilizing 'int' and '-1' as sentinel. Besides the smaller size advantage, this is simpler to serialize, as its internal representation is a single unsigned int as well.
2025-04-02[clang] Track final substitution for Subst* AST nodes (#132748)Matheus Izvekov1-30/+18
2025-04-01[clang] Concepts: support pack expansions for type constraints (#132626)Matheus Izvekov1-137/+9
This reverts an earlier attempt (adb0d8ddceb143749c519d14b8b31b481071da77 and 50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions, which was limited to type arguments and which subverted the purpose of SubstTemplateTypeParmType. This propagates the ArgumentPackSubstitutionIndex along with the AssociatedConstraint, so that the pack expansion works, without needing any new transforms or otherwise any changes to the template instantiation process. This keeps the tests from the reverted commits, and adds a few more showing the new solution also works for NTTPs. Fixes https://github.com/llvm/llvm-project/issues/131798
2025-03-22[Clang] Fix various bugs in alias CTAD transform (#132061)Younan Zhang1-12/+34
2025-03-21[OpenACC] Finish implementing 'routine' AST/Sema.erichkeane1-0/+8
This is the last item of the OpenACC 3.3 spec. It includes the implicit-name version of 'routine', plus significant refactorings to make the two work together. The implicit name version is represented as an attribute on the function call. This patch also implements the clauses for the implicit-name version, as well as the A.3.4 warning.
2025-03-10Revert "[clang] Implement instantiation context note for checking template ↵Nikita Popov1-24/+6
parameters (#126088)" This reverts commit a24523ac8dc07f3478311a5969184b922b520395. This is causing significant compile-time regressions for C++ code, see: https://github.com/llvm/llvm-project/pull/126088#issuecomment-2704874202
2025-03-06[clang] Implement instantiation context note for checking template ↵Matheus Izvekov1-6/+24
parameters (#126088) Instead of manually adding a note pointing to the relevant template parameter to every relevant error, which is very easy to miss, this patch adds a new instantiation context note, so that this can work using RAII magic. This fixes a bunch of places where these notes were missing, and is more future-proof. Some diagnostics are reworked to make better use of this note: - Errors about missing template arguments now refer to the parameter which is missing an argument. - Template Template parameter mismatches now refer to template parameters as parameters instead of arguments. It's likely this will add the note to some diagnostics where the parameter is not super relevant, but this can be reworked with time and the decrease in maintenance burden makes up for it. This bypasses the templight dumper for the new context entry, as the tests are very hard to update. This depends on #125453, which is needed to avoid losing the context note for errors occuring during template argument deduction.
2025-03-06[OpenACC] implement AST/Sema for 'routine' construct with argumenterichkeane1-0/+11
The 'routine' construct has two forms, one which takes the name of a function that it applies to, and another where it implicitly figures it out based on the next declaration. This patch implements the former with the required restrictions on the name and the function-static-variables as specified. What has not been implemented is any clauses for this, any of the A.3.4 warnings, or the other form.
2025-02-20[clang] print correct context for diagnostics suppressed by deduction (#125453)Matheus Izvekov1-135/+136
This patch makes it so the correct instantiation context is printed for diagnostics suppessed by template argument deduction. The context is saved along with the suppressed diagnostic, and when the declaration they were attached to becomes used, we print the correct context, instead of whatever context was at this point.
2025-02-18[Clang][P1061] Consolidate ResolvedUnpexandedPackExpr into ↵Jason Rice1-36/+11
FunctionParmPackExpr (#125394) This merges the functionality of ResolvedUnexpandedPackExpr into FunctionParmPackExpr. I also added a test to show that https://github.com/llvm/llvm-project/issues/125103 should be fixed with this. I put the removal of ResolvedUnexpandedPackExpr in its own commit. Let me know what you think. Fixes #125103
2025-02-14[Clang] Remove the PackExpansion restrictions for rewrite substitution (#126206)Younan Zhang1-16/+16
When substituting for rewrite purposes, as in rebuilding constraints for a synthesized deduction guide, it assumed that packs were in PackExpansion* form, such that the instantiator could extract a pattern. For type aliases CTAD, while rebuilding their associated constraints, this might not be the case because we'll call `TransformTemplateArgument()` for the alias template arguments, where there might be cases e.g. a non-pack expansion type into a pack expansion, so the assumption wouldn't hold. This patch fixes that by making it treat the non-pack expansions as direct patterns when rewriting. Fixes #124715
2025-02-05Reland: [clang] Track function template instantiation from definition (#125266)Matheus Izvekov1-5/+4
2025-02-05[clang] NFC: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (#125418)Matheus Izvekov1-9/+7
This rename follows the proposed wording in P3310R5, which introduces the term 'strict pack match' to refer to the same thing.
2025-02-05[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#125811)Kazu Hirata1-1/+1
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> Literal migration would result in dyn_cast_if_present (see the definition of PointerUnion::dyn_cast), but this patch uses dyn_cast because we expect Specialized to be nonnull. Note that if Specialized were null, dereferencing Tmpl would trigger a segfault.
2025-02-04[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#125630)Kazu Hirata1-1/+1
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> Literal migration would result in dyn_cast_if_present (see the definition of PointerUnion::dyn_cast), but this patch uses dyn_cast because we expect *Found to be nonnull. Note that if *Found were null, cast<VarDecl>(TransformedDecl) would trigger an assertion error.
2025-01-30Revert "[clang] Track function template instantiation from definition (#112241)"Martin Storsjö1-4/+5
This reverts commit 07a0e2be86f33beb6d519a3d466b95c2257e93cb. This change broke compiling Qt; see https://github.com/llvm/llvm-project/pull/112241 for details.
2025-01-29[Clang][P1061] Add stuctured binding packs (#121417)Jason Rice1-1/+28
This is an implementation of P1061 Structure Bindings Introduce a Pack without the ability to use packs outside of templates. There is a couple of ways the AST could have been sliced so let me know what you think. The only part of this change that I am unsure of is the serialization/deserialization stuff. I followed the implementation of other Exprs, but I do not really know how it is tested. Thank you for your time considering this. --------- Co-authored-by: Yanzuo Liu <zwuis@outlook.com>
2025-01-29[clang] Track function template instantiation from definition (#112241)Matheus Izvekov1-5/+4
This fixes instantiation of definition for friend function templates, when the declaration found and the one containing the definition have different template contexts. In these cases, the the function declaration corresponding to the definition is not available; it may not even be instantiated at all. So this patch adds a bit which tracks which function template declaration was instantiated from the member template. It's used to find which primary template serves as a context for the purpose of obtainining the template arguments needed to instantiate the definition. Fixes #55509 Relanding patch, with no changes, after it was reverted due to revert of commit this patch depended on.
2025-01-28[clang] disallow narrowing when matching template template parameters (#124313)Matheus Izvekov1-3/+4
This fixes the core issue described in P3579, following the design intent of P0522 to not introduce any new cases where a template template parameter match is allowed for a template which is not valid for all possible uses. With this patch, narrowing conversions are disallowed for TTP matching. This reuses the existing machinery for diagnosing narrowing in a converted constant expression. Since P0522 is a DR and we apply it all the way back to C++98, this brings that machinery to use in older standards, in this very narrow scope of TTP matching. This still doesn't solve the ambiguity when partial ordering NTTPs of different integral types, this is blocked by a different bug which will be fixed in a subsequent patch (but the test cases are added).
2025-01-27[Clang] Remove unnecessary Decl transform & profiles for SizeOfPackExpr ↵Younan Zhang1-26/+0
(#124533) We used to always transform the pattern declaration for SizeOfPackExpr to ensure the constraint expression's profile produced the desired result. However, this approach failed to handle pack expansions when the pack referred to function parameters. In such cases, the function parameters were formerly expanded to 1 to avoid building Subst* nodes (see e6974daa7). That workaround caused us to transform a pack without a proper ArgumentPackSubstitutionIndex, leading to crashes when transforming the pattern. It turns out that profiling the pattern for partially substituted SizeOfPackExprs is unnecessary because their transformed forms are also profiled within the partial arguments. Fixes https://github.com/llvm/llvm-project/issues/124161
2025-01-23Reland: [clang] unified CWG2398 and P0522 changes; finishes implementation ↵Matheus Izvekov1-10/+29
of P3310 (#124137) This patch relands the following PRs: * #111711 * #107350 * #111457 All of these patches were reverted due to an issue reported in https://github.com/llvm/llvm-project/pull/111711#issuecomment-2406491485, due to interdependencies. --- [clang] Finish implementation of P0522 This finishes the clang implementation of P0522, getting rid of the fallback to the old, pre-P0522 rules. Before this patch, when partial ordering template template parameters, we would perform, in order: * If the old rules would match, we would accept it. Otherwise, don't generate diagnostics yet. * If the new rules would match, just accept it. Otherwise, don't generate any diagnostics yet again. * Apply the old rules again, this time with diagnostics. This situation was far from ideal, as we would sometimes: * Accept some things we shouldn't. * Reject some things we shouldn't. * Only diagnose rejection in terms of the old rules. With this patch, we apply the P0522 rules throughout. This needed to extend template argument deduction in order to accept the historial rule for TTP matching pack parameter to non-pack arguments. This change also makes us accept some combinations of historical and P0522 allowances we wouldn't before. It also fixes a bunch of bugs that were documented in the test suite, which I am not sure there are issues already created for them. This causes a lot of changes to the way these failures are diagnosed, with related test suite churn. The problem here is that the old rules were very simple and non-recursive, making it easy to provide customized diagnostics, and to keep them consistent with each other. The new rules are a lot more complex and rely on template argument deduction, substitutions, and they are recursive. The approach taken here is to mostly rely on existing diagnostics, and create a new instantiation context that keeps track of this context. So for example when a substitution failure occurs, we use the error produced there unmodified, and just attach notes to it explaining that it occurred in the context of partial ordering this template argument against that template parameter. This diverges from the old diagnostics, which would lead with an error pointing to the template argument, explain the problem in subsequent notes, and produce a final note pointing to the parameter. --- [clang] CWG2398: improve overload resolution backwards compat With this change, we discriminate if the primary template and which partial specializations would have participated in overload resolution prior to P0522 changes. We collect those in an initial set. If this set is not empty, or the primary template would have matched, we proceed with this set as the candidates for overload resolution. Otherwise, we build a new overload set with everything else, and proceed as usual. --- [clang] Implement TTP 'reversed' pack matching for deduced function template calls. Clang previously missed implementing P0522 pack matching for deduced function template calls.
2025-01-17[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#123284)Kazu Hirata1-1/+1
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> Literal migration would result in dyn_cast_if_present (see the definition of PointerUnion::dyn_cast), but this patch uses dyn_cast because we expect Stored to be nonnull.
2025-01-08Revert "[Clang] Implement CWG2369 "Ordering between constraints and ↵Younan Zhang1-104/+11
substitution"" (#122130) Unfortunately that breaks some code on Windows when lambdas come into play, as reported in https://github.com/llvm/llvm-project/pull/102857#issuecomment-2577861178 This reverts commit 96eced624e0f120155256033fdcb8342e7e58d6e.
2025-01-05[Clang] Implement CWG2369 "Ordering between constraints and substitution" ↵Younan Zhang1-11/+104
(#102857) This patch partially implements CWG2369 for non-lambda-constrained functions. Lambdas are left intact at this point because we need extra work to correctly instantiate captures before the function instantiation. As a premise of CWG2369, this patch also implements CWG2770 to ensure the function parameters are instantiated on demand. Closes https://github.com/llvm/llvm-project/issues/54440
2024-11-27[Sema] Migrate away from PointerUnion::{is,get} (NFC) (#117498)Kazu Hirata1-6/+6
Note that PointerUnion::{is,get} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> I'm not touching PointerUnion::dyn_cast for now because it's a bit complicated; we could blindly migrate it to dyn_cast_if_present, but we should probably use dyn_cast when the operand is known to be non-null.
2024-11-16[Sema] Remove unused includes (NFC) (#116461)Kazu Hirata1-2/+0
Identified with misc-include-cleaner.
2024-11-15[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use ↵Sirraide1-3/+3
DynamicRecursiveASTVisitor (#115144) This pr refactors all recursive AST visitors in `Sema`, `Analyze`, and `StaticAnalysis` to inherit from DRAV instead. This is over half of the visitors that inherit from RAV directly. See also #115132, #110040, #93462 LLVM Compile-Time Tracker link for this branch: https://llvm-compile-time-tracker.com/compare.php?from=5adb5c05a2e9f31385fbba8b0436cbc07d91a44d&to=b58e589a86c06ba28d4d90613864d10be29aa5ba&stat=instructions%3Au
2024-11-12[Clang] Fix dependent expression handling for assumptions (#115646)Younan Zhang1-2/+9
The function definition instantiation assumes any declarations used inside are already transformed before transforming the body, so we need to preserve the transformed expression of CXXAssumeAttr even if it is not a constant expression. Moreover, the full expression of the assumption should also entail a potential lambda capture transformation, hence the call to ActOnFinishFullExpr() after TransformExpr(). Fixes #114787
2024-11-08[Clang] Remove the wrong assumption when rebuilding SizeOfPackExprs for ↵Younan Zhang1-25/+24
constraint normalization (#115120) In 463a4f150, we assumed that all the template argument packs are of size 1 when normalizing a constraint expression because I mistakenly thought those packs were obtained from their injected template parameters. This was wrong because we might be checking constraints when instantiating a friend declaration within a class template specialization, where the parent class template is specialized with non-dependent template arguments. In that sense, we shouldn't assume any pack size nor expand anything in such a scenario. Moreover, there are no intermediate (substituted but unexpanded) AST nodes for template template parameters, so we have to special-case their transformations by looking into the instantiation scope instead of extracting anything from template arguments. Fixes #115098
2024-11-07[Clang] Distinguish expanding-pack-in-place cases for ↵Younan Zhang1-11/+24
SubstTemplateTypeParmTypes (#114220) In 50e5411e4, we preserved the pack substitution index within SubstTemplateTypeParmType nodes and performed in-place expansions of packs such that type constraints on a lambda that serve as a pattern of a fold expression could be evaluated if the type constraints contain any packs that are expanded by the fold expression. However, we made an incorrect assumption of the condition under which in-place expansion should occur. For example, a SizeOfPackExpr case relies on SubstTemplateTypeParmType nodes being transformed to SubstTemplateTypeParmPackTypes rather than expanding them immediately in place. This fixes that by adding a flag to SubstTemplateTypeParmType to discriminate such in-place expansion situations. Fixes https://github.com/llvm/llvm-project/issues/113518
2024-11-06Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template ↵Krystian Stasiowski1-362/+385
argument lists (#106585, #111173)" (#111852)" (#115159) This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136.
2024-11-06Revert "[Clang][Sema] Use the correct injected template arguments for ↵Krystian Stasiowski1-4/+2
partial specializations when collecting multi-level template argument lists (#112381)" (#115157) This reverts commit 9381c6fd04cc16a7606633f57c96c11e58181ddb.
2024-11-06Revert "Reapply "[Clang][Sema] Always use latest redeclaration of primary ↵Krystian Stasiowski1-7/+7
template" (#114569)" (#115156) This reverts commit b24650e814e55d90acfc40acf045456c98f32b9c.
2024-11-01Reapply "[Clang][Sema] Always use latest redeclaration of primary template" ↵Krystian Stasiowski1-7/+7
(#114569) This patch reapplies #114258, fixing an infinite recursion bug in `ASTImporter` that occurs when importing the primary template of a class template specialization when the latest redeclaration of that template is a friend declaration in the primary template.
2024-10-30Revert "[Clang][Sema] Always use latest redeclaration of primary template" ↵Felipe de Azevedo Piovezan1-7/+7
(#114304) Clang importer doesn't seem to work well with this change, see discussion in the original PR. Reverts llvm/llvm-project#114258
2024-10-30[Clang][Sema] Always use latest redeclaration of primary template (#114258)Krystian Stasiowski1-7/+7
This patch fixes a couple of regressions introduced in #111852. Consider: ``` template<typename T> struct A { template<bool U> static constexpr bool f() requires U { return true; } }; template<> template<bool U> constexpr bool A<short>::f() requires U { return A<long>::f<U>(); } template<> template<bool U> constexpr bool A<long>::f() requires U { return true; } static_assert(A<short>::f<true>()); // crash here ``` This crashes because when collecting template arguments from the _first_ declaration of `A<long>::f<true>` for constraint checking, we don't add the template arguments from the enclosing class template specialization because there exists another redeclaration that is a member specialization. This also fixes the following example, which happens for a similar reason: ``` // input.cppm export module input; export template<int N> constexpr int f(); template<int N> struct A { template<int J> friend constexpr int f(); }; template struct A<0>; template<int N> constexpr int f() { return N; } ``` ``` // input.cpp import input; static_assert(f<1>() == 1); // error: static assertion failed ```
2024-10-30[Clang][Sema] Ignore previous partial specializations of member templates ↵Krystian Stasiowski1-6/+32
explicitly specialized for an implicitly instantiated class template specialization (#113464) Consider the following: ``` template<typename T> struct A { template<typename U> struct B { static constexpr int x = 0; // #1 }; template<typename U> struct B<U*> { static constexpr int x = 1; // #2 }; }; template<> template<typename U> struct A<long>::B { static constexpr int x = 2; // #3 }; static_assert(A<short>::B<int>::y == 0); // uses #1 static_assert(A<short>::B<int*>::y == 1); // uses #2 static_assert(A<long>::B<int>::y == 2); // uses #3 static_assert(A<long>::B<int*>::y == 2); // uses #3 ``` According to [temp.spec.partial.member] p2: > If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template. If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template. The example above fails to compile because we currently don't implement [temp.spec.partial.member] p2. This patch implements the wording, fixing #51051.