================ @@ -501,6 +519,89 @@ bool Sema::CheckEquivalentExceptionSpec( return Result; } +static const Expr *SubstituteExceptionSpecWithoutEvaluation( + Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo, + const Expr *ExceptionSpec) { + MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( + DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), + /*Final=*/false, /*Innermost=*/std::nullopt, + /*RelativeToPrimary=*/true, /*ForConstraintInstantiation=*/true); + + if (!MLTAL.getNumSubstitutedLevels()) + return ExceptionSpec; + + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false); + + Sema::InstantiatingTemplate Inst( + S, DeclInfo.getLocation(), + const_cast<FunctionDecl *>(DeclInfo.getDecl()->getAsFunction()), + Sema::InstantiatingTemplate::ExceptionSpecification()); + if (Inst.isInvalid()) + return nullptr; + + // Set up a dummy 'instantiation' scope in the case of reference to function + // parameters that the surrounding function hasn't been instantiated yet. Note + // this may happen while we're comparing two templates' constraint + // equivalence. + LocalInstantiationScope ScopeForParameters(S); + if (auto *FD = DeclInfo.getDecl()->getAsFunction()) + for (auto *PVD : FD->parameters()) + ScopeForParameters.InstantiatedLocal(PVD, PVD); + + std::optional<Sema::CXXThisScopeRAII> ThisScope; + + // See TreeTransform::RebuildTemplateSpecializationType. A context scope is + // essential for having an injected class as the canonical type for a template + // specialization type at the rebuilding stage. This guarantees that, for + // out-of-line definitions, injected class name types and their equivalent + // template specializations can be profiled to the same value, which makes it + // possible that e.g. constraints involving C<Class<T>> and C<Class> are + // perceived identical. + std::optional<Sema::ContextRAII> ContextScope; ---------------- mizvekov wrote:
So ContextRAII saves, changes and restores the CurContext. This is the current semantic context which will be used as the parent of any top level declarations created within the substitution below. The DelcContext here could also be something else, like a namespace, and we would for example want a lambda appearing within the exception spec to be parented to that, instead of whatever just happens to be the CurContext. Also, the semantic context of the exception spec should be the function, not the parent of the function. ```suggestion Sema::ContextRAII ContextScope(S, FD); ``` https://github.com/llvm/llvm-project/pull/111561 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits