<div dir="ltr"><div dir="ltr">On Tue, 11 Aug 2020 at 00:29, Martin Storsjö <<a href="mailto:martin@martin.st">martin@martin.st</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sun, 9 Aug 2020, Richard Smith via cfe-commits wrote:<br>
<br>
><br>
> Author: Richard Smith<br>
> Date: 2020-08-09T23:22:26-07:00<br>
> New Revision: 617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9<br>
><br>
> URL: <a href="https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9</a><br>
> DIFF: <a href="https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9.diff</a><br>
><br>
> LOG: Improve modeling of variable template specializations with dependent<br>
> arguments.<br>
><br>
> Don't build a variable template specialization declaration until its<br>
> scope and template arguments are non-dependent.<br>
><br>
> No functionality change intended, but the AST representation is now more<br>
> consistent with how we model other templates.<br>
<br>
This did turn out to make a functional change, breaking building the dev <br>
branch of Qt. A halfway reduced example below:<br></blockquote><div><br></div><div>Thanks for reporting this! Reduced a bit more:</div><div><br></div><div>template<class _Tp, class _Arg><br>inline constexpr bool is_nothrow_assignable_v = true;<br><br>template<class T> class QCache {<br>    void replace() noexcept(is_nothrow_assignable_v<T>);<br>};<br></div><div><br></div><div>We used to allow this and now reject. This code is ill-formed (no diagnostic required) by [temp.res]/8, because it has no valid instantiations, because the second template argument of is_nothrow_assignable_v is missing.</div><div><br></div><div>So, assuming the case from which this was reduced was similarly ill-formed (which it looks like it is: <a href="https://github.com/qt/qtbase/blob/48c8322a613f58d19ad9e0262bbac437ce2598f8/src/corelib/tools/qcache.h#L114">https://github.com/qt/qtbase/blob/48c8322a613f58d19ad9e0262bbac437ce2598f8/src/corelib/tools/qcache.h#L114</a>), I think that's a (minor) quality of implementation improvement -- we now diagnose a bug that we used to miss. ICC also rejects this, although GCC does not, and all three compilers reject the corresponding case using a class template instead of a variable template.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
template <class _Tp, _Tp __v><br>
struct integral_constant<br>
{<br>
   static constexpr const _Tp value = __v;<br>
   typedef _Tp value_type;<br>
   typedef integral_constant type;<br>
   __attribute__ ((__exclude_from_explicit_instantiation__))<br>
   constexpr operator value_type() const noexcept {return value;}<br>
<br>
   __attribute__ ((__exclude_from_explicit_instantiation__))<br>
   constexpr value_type operator ()() const noexcept {return value;}<br>
};<br>
<br>
<br>
template <class _Tp, class _Arg><br>
struct is_nothrow_assignable<br>
     : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> <br>
{};<br>
template <class _Tp, class _Arg><br>
inline constexpr bool is_nothrow_assignable_v<br>
     = is_nothrow_assignable<_Tp, _Arg>::value;<br>
<br>
<br>
template <class T><br>
class QCache<br>
{<br>
     struct Value {<br>
         T *t = nullptr;<br>
     };<br>
<br>
     struct Node {<br>
         Value value;<br>
<br>
         void replace(const Value &t) noexcept(is_nothrow_assignable_v<T>) {<br>
             value = t;<br>
         }<br>
     };<br>
<br>
};<br>
<br>
<br>
<br>
// Martin<br>
<br>
</blockquote></div></div>