[LLVMbugs] [Bug 7263] New: friend declaration confuses name lookup

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun May 30 13:01:30 PDT 2010


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: unassignedclangbugs at nondot.org
        ReportedBy: dimitry at andric.com
                CC: llvmbugs at cs.uiuc.edu, dgregor at apple.com


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.



More information about the llvm-bugs mailing list