The dependence of a template argument is not only determined by the argument itself, but also by the type of the template parameter: > Furthermore, a non-type [template-argument](https://eel.is/c++draft/temp.names#nt:template-argument) is dependent if the corresponding non-type [template-parameter](https://eel.is/c++draft/temp.param#nt:template-parameter) is of reference or pointer type and the [template-argument](https://eel.is/c++draft/temp.names#nt:template-argument) designates or points to a member of the current instantiation or a member of a dependent type[.](https://eel.is/c++draft/temp.dep#temp-3.sentence-1) For example: ```cpp struct A{}; template <const A& T> const A JoinStringViews = T; template <int V> class Builder { public: static constexpr A Equal{}; static constexpr auto Val = JoinStringViews<Equal>; }; ``` The constant expression `Equal` is not dependent, but because the type of the template parameter is a reference type and `Equal` is a member of the current instantiation, the template argument of `JoinStringViews<Equal>` is actually dependent, which makes `JoinStringViews<Equal>` dependent. When a template-id of a variable template is dependent, `CheckVarTemplateId` will return an `UnresolvedLookupExpr`, but `UnresolvedLookupExpr` calculates dependence by template arguments only (the `ConstantExpr` `Equal` here), which is not dependent. This causes type deduction to think that `JoinStringViews<Equal>` is `OverloadTy` and treat it as a function template, which is clearly wrong. This PR adds a `KnownDependent` parameter to the constructor of `UnresolvedLookupExpr`. After canonicalization, if `CanonicalConverted` contains any dependent argument, `KnownDependent` is set to `true`. This fixes the dependence calculation of `UnresolvedLookupExpr` for dependent variable templates. Fixes #65153 .
3.8 KiB
3.8 KiB