diff mbox

[wwwdocs] Add a case to porting_to + a question wrt validity of another one

Message ID 20170207140409.GF13736@redhat.com
State New
Headers show

Commit Message

Marek Polacek Feb. 7, 2017, 2:04 p.m. UTC
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 &lt;typename&gt; 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 &lt;class&gt; 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 &lt;class T&gt; void B&lt;T&gt;::m_fn1() { foo (this-&gt;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 &lt;typename&gt; class B : A {
> > +  void m_fn1() { this-&gt;a[0]; }
> 
> s/m_fn1/fn1/ again

Fixed.

Thanks much for the review.  Looks ok now?


	Marek

Comments

Jonathan Wakely Feb. 7, 2017, 2:13 p.m. UTC | #1
On 07/02/17 15:04 +0100, Marek Polacek wrote:
>Thanks much for the review.  Looks ok now?

Looks great.
Jason Merrill Feb. 7, 2017, 9:17 p.m. UTC | #2
On Tue, Feb 7, 2017 at 9:13 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 07/02/17 15:04 +0100, Marek Polacek wrote:
>>
>> Thanks much for the review.  Looks ok now?

I'd suggest adding something to say that the reason these are now
being diagnosed is that G++ used to treat e.g. this->member, where
member has a non-dependent type, as type-dependent, and now it
doesn't.

Jason
diff mbox

Patch

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 &lt;typename&gt; 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 &lt;typename&gt; struct B : A {
+  void fn1() { foo (this-&gt;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 &lt;typename&gt; class B : A {
+  void fn1() { this-&gt;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>