[cfe-dev] Three code snippets accepted by clang and rejected by g++

Nikola Smiljanic popizdeh at gmail.com
Sun Aug 10 17:26:45 PDT 2014


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.

  EffectiveContext EC(S.CurContext);

Current context here is class B and that doesn't seem right, added John as
he's the author.


On Mon, Aug 11, 2014 at 12:10 AM, Nicola Gigante <nicola.gigante at gmail.com>
wrote:

> Hello.
>
> While testing a recently written piece of code to see if it worked on linux
> I found three differences between clang and g++ that make the first
> to compile the code and the second to reject it. I'm talking about the
> clang shipped with Xcode 5.1.1, I don't have a working trunk and my
> machine is slow to compile, sorry.
>
> Below the three issues:
>
> 1) transitive-friend.cpp
> class A {
>   friend class B;
>   int v;
> };
>
> struct B {
>   A a;
>   friend int f(B b) {
>      return b.a.v;
>   }
> };
>
> Clang accept this code because
> I access the private field of A in the scope of B
> and B is a friend. g++ rejects it:
>
> $ g++-4.9 -std=c++11 -fsyntax-only differences.cpp
> differences.cpp: In function 'int f(B)':
> differences.cpp:3:7: error: 'int A::v' is private
>    int v;
>        ^
> differences.cpp:9:17: error: within this context
>       return b.a.v;
>                  ^
>
> 2) templatebase.cpp
> template<typename T>
> struct A {
>    template<typename U>
>    struct B {
>
>    };
>
>    struct C;
> };
>
> template<typename T>
> struct A<T>::C : public A<T>::B<int> // public A<T>::template B<int>
> {
>
> };
>
> Is the template keyword needed here? Note that if you move out
> struct C so that it isn't a member of A anymore, clang correctly
> says that I need the template keyword. g++ wants the keyword
> in both cases:
>
> $ g++-4.9 -std=c++11 -fsyntax-only templatebase.cpp
> 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
>  struct A<T>::C : public A<T>::B<int> {
>                                     ^
> 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
>  struct A<T>::C : public A<T>::B<int> {
>                                ^
> templatebase.cpp:12:38: error: expected class-name before '{' token
>  struct A<T>::C : public A<T>::B<int> {
>                                       ^
> 3) tupleconstructor.cpp
> #include <tuple>
>
> std::tuple<int, int, int>
> func() {
>    return { 0, 1, 2 };
> }
>
> I don't know how to phrase the situation in standardese terms (is it
> list-initialization?).
> It seems to me that clang picks the forwarding constructor, g++ the
> explicit initializer-list constructor.
>
> $ g++-4.9 -std=c++11 -fsyntax-only tupleconstructor.cpp
> tupleconstructor.cpp: In function 'std::tuple<int, int, int> func()':
> 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}]'
>     return { 0, 1, 2 };
>                      ^
>
> In all these three cases, who is right? Are these bugs in clang?
> In this case, should I make a separate bug report for each case, right?
> I've attached the single test cases
>
> Greetings,
> Nicola
>
>
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140811/ecf33148/attachment.html>


More information about the cfe-dev mailing list