On Tue, Feb 07, 2017 at 01:44:44PM +0000, Jonathan Wakely wrote: > On 07/02/17 14:27 +0100, Marek Polacek wrote: > > > You could drop the namespace. Also "struct A" would be better, because > > > otherwise fn1 is a private and thus unaccessible in fn2. > > > > True. So how about this extended version, which also mentions more examples > > of what might now fail? > > > > Index: porting_to.html > > =================================================================== > > RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-7/porting_to.html,v > > retrieving revision 1.3 > > diff -u -r1.3 porting_to.html > > --- porting_to.html 3 Feb 2017 07:55:27 -0000 1.3 > > +++ porting_to.html 7 Feb 2017 13:27:28 -0000 > > @@ -33,6 +33,68 @@ > > > > <h2 id="cxx">C++ language issues</h2> > > > > +<h3 id="hypothetical-instantiation">Stricter rules when using > > templates</h3> > > + > > +<p> > > +GCC 7 no longer accepts various ill-formed code involving use of templates. > > +The C++ standard says: > > +</p> > > + > > +<p><em> > > +14.6/8: "If a hypothetical instantiation of a template immediately > > +following its definition would be ill-formed due to a construct that > > +does not depend on a template parameter, the program is ill-formed; no > > +diagnostic is required. If the interpretation of such a construct in > > +the hypothetical instantiation is different from the interpretation of > > +the corresponding construct in any actual instantiation of the > > +template, the program is ill-formed; no diagnostic is required." > > +</em></p> > > + > > +<p> > > +As a consequence, the following examples are now invalid and G++ will no > > longer > > I'd remove "now" since they've always been invalid, we just didn't > diagnose them until now.
Right, removed. > > +compile them: > > +<pre><code> > > +struct C; > > +struct A { > > + C fn1(); > > +}; > > +template <typename> class B : A { > > + void fn2() { fn1().x; } > > +}; > > +</code></pre> > > +will result in > > +<blockquote><pre> > > +<span class="boldred">error:</span> invalid use of incomplete type > > <b>'struct C'</b> > > +</pre></blockquote> > > + > > +<pre><code> > > +class A { > > Make this a struct, not a class. Otherwise the code would also be > invalid because of an access error, which isn't relevant to the > example. Okay. > > + int m_class; > > I suggest changing "m_class" (in both places) to something more > generic, like "m_val" or just "x". And "m_fn1" is a funny member > function name, "fn1" (as in the previous example) would be better. Done. I think creduce came up with these names. > > +}; > > +template <class> class B : A { void m_fn1(); }; > > Unless you want to vary the examples intentionally, I'd change "<class>" > to "<typename>" for consistency with the other two examples. The > fewer unrelated differences between the examples the better, so users > don't waste time wondering if the unrelated differences are > significant to the example. > > > +template <class T> void B<T>::m_fn1() { foo > > (this->m_class); } > > This function could be defined inline, as in the previous example. > Whether it's defined out of the class body isn't relevant. > > So simply: > > struct A { > int x; > }; > template<typename> struct B : A { > void fn1() { foo (this->x); } > }; Donezo. > > > +</code></pre> > > +will result in > > +<blockquote><pre> > > +<span class="boldred">error:</span> there are no arguments to <b>'foo'</b> > > that depend on a template parameter, so a declaration of <b>'foo'</b> must > > be available > > +</pre></blockquote> > > + > > +<pre><code> > > +class A { > > This can be a struct again. > > > + void *a; > > Idiomatic C++ would say "void* a" not "void *a" but you could use > "void * a" to keep both groups of people happy ;-) > > > +}; > > +template <typename> class B : A { > > + void m_fn1() { this->a[0]; } > > s/m_fn1/fn1/ again Fixed. Thanks much for the review. Looks ok now? Index: porting_to.html =================================================================== RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-7/porting_to.html,v retrieving revision 1.3 diff -u -r1.3 porting_to.html --- porting_to.html 3 Feb 2017 07:55:27 -0000 1.3 +++ porting_to.html 7 Feb 2017 14:03:42 -0000 @@ -33,6 +33,69 @@ <h2 id="cxx">C++ language issues</h2> +<h3 id="hypothetical-instantiation">Stricter rules when using templates</h3> + +<p> +GCC 7 no longer accepts various ill-formed code involving use of templates. +The C++ standard says: +</p> + +<p><em> +14.6/8: "If a hypothetical instantiation of a template immediately +following its definition would be ill-formed due to a construct that +does not depend on a template parameter, the program is ill-formed; no +diagnostic is required. If the interpretation of such a construct in +the hypothetical instantiation is different from the interpretation of +the corresponding construct in any actual instantiation of the +template, the program is ill-formed; no diagnostic is required." +</em></p> + +<p> +As a consequence, the following examples are invalid and G++ will no longer +compile them: +<pre><code> +struct C; +struct A { + C fn1(); +}; +template <typename> class B : A { + void fn2() { fn1().x; } +}; +</code></pre> +will result in +<blockquote><pre> +<span class="boldred">error:</span> invalid use of incomplete type <b>'struct C'</b> +</pre></blockquote> + +<pre><code> +struct A { + int x; +}; +template <typename> struct B : A { + void fn1() { foo (this->x); } +}; +</code></pre> +will result in +<blockquote><pre> +<span class="boldred">error:</span> there are no arguments to <b>'foo'</b> that depend on a template parameter, so a declaration of <b>'foo'</b> must be available +</pre></blockquote> + +<pre><code> +struct A { + void* a; +}; +template <typename> class B : A { + void fn1() { this->a[0]; } +}; +</code></pre> +will result in +<blockquote><pre> +<span class="boldred">error:</span> <b>'void*'</b> is not a pointer-to-object type +</pre></blockquote> +because there's no instantiation of that template that can be valid, it will +always dereference a <code>void*</code>. +</p> + <h3 id="conversion-op-mangling">Mangling change for conversion operators</h3> <p> Marek