[LLVMbugs] [Bug 9785] New: Template friend in namespace doesn't work correctly.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Apr 23 14:08:41 PDT 2011


http://llvm.org/bugs/show_bug.cgi?id=9785

           Summary: Template friend in namespace doesn't work correctly.
           Product: clang
           Version: 2.9
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: eteran at alum.rit.edu
                CC: llvmbugs at cs.uiuc.edu, dgregor at apple.com


So I have some code which looks roughly like this:

----------
namespace detail {
    template <class T>
    struct Info {
        template <class X> friend struct Test;    
    protected:
        Info(int) {}
    };
}

template <class T>
struct Test {
    typedef detail::Info<T> info;
    struct Wrapper {
        explicit Wrapper(info) {
        };
    };
    Wrapper f() { return Wrapper(info(0)); }
};

int main() {
    Test<int> x;
    x.f();
}
----------

g++-4.5.2 accepts this code, but clang++-2.9 rejects it with the following
error:

----------
$ clang++ -ansi -pedantic -W -Wall test.cc -o test
test.cc:18:31: error: calling a protected constructor of class
'detail::Info<int>'
        Wrapper f() { return Wrapper(info(0)); }
                                     ^
test.cc:24:4: note: in instantiation of member function 'Test<int>::f'
requested here                                                                  
        x.f();
          ^
test.cc:7:3: note: declared protected here                                      
                Info(int) {}
                ^
1 error generated.
----------

Interestingly enough, if I remove the "detail" namespace, then the code is
accepted by both compilers without issue. I honestly don't know if g++ or
clang++ is correct in this case, but the code does seem reasonable to me. If it
does turn out that g++ is erroneously accepting the code, then I will file a
bug report with them as well.

Another aspect that is very odd, is that if I remove the template aspect of the
"Info" class, then both g++ and clang++ reject the code with similar errors.
Like this:

----------
namespace detail {
    struct Info {
        template <class X> friend struct Test;    
    protected:
        Info(int) {}
    };
}

template <class T>
struct Test {
    typedef detail::Info info;
    struct Wrapper {
        explicit Wrapper(info) {
        };
    };
    Wrapper f() { return Wrapper(info(0)); }
};


int main() {
    Test<int> x;
    x.f();
}
----------

But once again, both accept the code if I remove the "detail" namespace. It
seems that both g++ and clang++ have some quirkiness when combining templates,
namespaces and friends.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list