<div dir="ltr">I'd say the first one is a clang bug. Friends are not transitive, the problem is in the implementation of class.protected restriction inside CheckAccess function.<div><br></div><div><div> EffectiveContext EC(S.CurContext);</div>
<div><br></div></div><div>Current context here is class B and that doesn't seem right, added John as he's the author.<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 11, 2014 at 12:10 AM, Nicola Gigante <span dir="ltr"><<a href="mailto:nicola.gigante@gmail.com" target="_blank">nicola.gigante@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello.<br>
<br>
While testing a recently written piece of code to see if it worked on linux<br>
I found three differences between clang and g++ that make the first<br>
to compile the code and the second to reject it. I'm talking about the<br>
clang shipped with Xcode 5.1.1, I don't have a working trunk and my<br>
machine is slow to compile, sorry.<br>
<br>
Below the three issues:<br>
<br>
1) transitive-friend.cpp<br>
class A {<br>
friend class B;<br>
int v;<br>
};<br>
<br>
struct B {<br>
A a;<br>
friend int f(B b) {<br>
return b.a.v;<br>
}<br>
};<br>
<br>
Clang accept this code because<br>
I access the private field of A in the scope of B<br>
and B is a friend. g++ rejects it:<br>
<br>
$ g++-4.9 -std=c++11 -fsyntax-only differences.cpp<br>
differences.cpp: In function 'int f(B)':<br>
differences.cpp:3:7: error: 'int A::v' is private<br>
int v;<br>
^<br>
differences.cpp:9:17: error: within this context<br>
return b.a.v;<br>
^<br>
<br>
2) templatebase.cpp<br>
template<typename T><br>
struct A {<br>
template<typename U><br>
struct B {<br>
<br>
};<br>
<br>
struct C;<br>
};<br>
<br>
template<typename T><br>
struct A<T>::C : public A<T>::B<int> // public A<T>::template B<int><br>
{<br>
<br>
};<br>
<br>
Is the template keyword needed here? Note that if you move out<br>
struct C so that it isn't a member of A anymore, clang correctly<br>
says that I need the template keyword. g++ wants the keyword<br>
in both cases:<br>
<br>
$ g++-4.9 -std=c++11 -fsyntax-only templatebase.cpp<br>
templatebase.cpp:12:36: error: 'typename A<T>::B' names 'template<class T> template<class U> struct A<T>::B', which is not a type<br>
struct A<T>::C : public A<T>::B<int> {<br>
^<br>
templatebase.cpp:12:31: error: 'typename A<T>::B' names 'template<class T> template<class U> struct A<T>::B', which is not a type<br>
struct A<T>::C : public A<T>::B<int> {<br>
^<br>
templatebase.cpp:12:38: error: expected class-name before '{' token<br>
struct A<T>::C : public A<T>::B<int> {<br>
^<br>
3) tupleconstructor.cpp<br>
#include <tuple><br>
<br>
std::tuple<int, int, int><br>
func() {<br>
return { 0, 1, 2 };<br>
}<br>
<br>
I don't know how to phrase the situation in standardese terms (is it list-initialization?).<br>
It seems to me that clang picks the forwarding constructor, g++ the explicit initializer-list constructor.<br>
<br>
$ g++-4.9 -std=c++11 -fsyntax-only tupleconstructor.cpp<br>
tupleconstructor.cpp: In function 'std::tuple<int, int, int> func()':<br>
tupleconstructor.cpp:5:21: error: converting to 'std::tuple<int, int, int>' from initializer list would use explicit constructor 'constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, int, int}; <template-parameter-2-2> = void; _Elements = {int, int, int}]'<br>
return { 0, 1, 2 };<br>
^<br>
<br>
In all these three cases, who is right? Are these bugs in clang?<br>
In this case, should I make a separate bug report for each case, right? I've attached the single test cases<br>
<br>
Greetings,<br>
Nicola<br>
<br>
<br>
<br><br>
<br>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>