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

           Summary: friend declaration confuses name lookup
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
        AssignedTo: [email protected]
        ReportedBy: [email protected]
                CC: [email protected], [email protected]


During building of the pango 1.28.0 port on FreeBSD, we encountered the
following fragment of code that gave compile errors with clang, but not
with gcc:

========================================
struct LookupSubTable {
};

struct Extension {
  const LookupSubTable& get_subtable (void) const;
};

struct ExtensionSubst : Extension {
  friend struct SubstLookupSubTable;
  inline const struct SubstLookupSubTable& get_subtable (void) const {
    return (*(reinterpret_cast<const SubstLookupSubTable
*>((reinterpret_cast<const char *>(&(Extension::get_subtable ()))) + 0)));
  }
};
========================================

which produces (with llvm/clang r105165):

pangotest.cpp:11:38: error: unknown type name 'SubstLookupSubTable'
    return (*(reinterpret_cast<const SubstLookupSubTable
*>((reinterpret_cast<const char *>(&(Extension::get_subtable ()))) + 0)));
                                     ^
pangotest.cpp:11:12: error: reference to type 'struct SubstLookupSubTable
const' could not bind to an lvalue of type 'char const'
    return (*(reinterpret_cast<const SubstLookupSubTable
*>((reinterpret_cast<const char *>(&(Extension::get_subtable ()))) + 0)));
          
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The fragment can be further reduced to (thanks Benjamin):

class Bar {
  friend class Foo;
  class Foo *test() { return (Foo *)0; }
};

giving:

friendtest1.cpp:3:31: error: use of undeclared identifier 'Foo'
  class Foo *test() { return (Foo *)0; }
                              ^

Which compiles fine with gcc 4.2.1 (the FreeBSD default compiler), but
also MS VC++ has no problems with it.

This issue is similar to, but not exactly the same as bug 6759: the
"friend class Foo" line is apparently NOT enough to fully declare class
Foo, however the "class Foo *test()" function declaration should be.

In fact, this fragment compiles fine:

class Bar {
  class Foo *test() { return (Foo *)0; }
};

so adding the "friend class Foo" really seems to change something in the
name lookup.

It gets even stranger when using a fully specified return type in the
member function:

class Bar {
  friend class Foo;
  class Foo *test() { return (class Foo *)0; }
};

resulting in:

friendtest2.cpp:3:30: error: cannot initialize return object of type 'class Foo
*' with an rvalue of type 'class Foo *'
  class Foo *test() { return (class Foo *)0; }
                             ^~~~~~~~~~~~~~

which is, though quite funny, a rather confusing error message. :)

-- 
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.
_______________________________________________
LLVMbugs mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs

Reply via email to