[PATCH] D16989: Change interpretation of function definition in friend declaration of template class.

Serge Pavlov via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 1 10:20:40 PDT 2016


sepavloff updated this revision to Diff 70025.
sepavloff added a comment.

Fixed DR136 for template classes

Previously clang created declarations of friend functions declared in template classes even
if that class was not instantiated. It allowed to make check for default arguments required
by DR136. This fix enables the check for the new implementation.

Also extended comment about putting friend function declarations into redeclaration chains.

Putting a friend declaration to the appropriate redeclaration chain is not necessary, any
errors in the declaration will be detected at instantiation time. However proper organization
of the declarations enables early detection of potential problems.

If a friend function is defined inline, it is almost certain that it should not be added to
the redeclaration chain. The following code demonstrates the problem:

  void func();
  template<typename T> class C1 {
      friend void func() {}
  };
  template<typename T> class C2 {
      friend void func() {}
  }

Putting definitions of the friend functions into the same chain would require additional flag
to distinguish between 'actual' and 'potential' definitions. Operation with the chain becomes
more complicated. Putting only 'actual' definitions saves from the need to modify the mechanism
of redeclaration chain.

Putting non-defining declaration into the chain seems unnecessary. If there is corresponding
declaration at namespace level, as in the code:

  void func();
  template<typename T> class C1 {
      friend bool func() {}    // <- cannot be redeclared with different return type
  };

compiler can detect invalid redeclaration because it finds prior declaration in the translation
unit in this example. Declaration of the friend function does not need to be saved for any check
in this case.

If there is no the function declaration at namespace level, putting non-defining declaration into
the chain can cause problems, for instance:

  template<typename T> class C1 {
      friend void func() {}
  };
  template<typename T> class C2 {
      friend bool func() {}    // <- different return type
  }

This code does not violates any requirement of the C++ standard. Only if both templates are
instantiated, code becomes ill-formed. But these friend function declarations cannot be put into
the same redeclaration chain.

So, friend function declarations defined in dependent context that names file-level functions
should not be put into redeclaration chain.


https://reviews.llvm.org/D16989

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/SemaCXX/PR25848.cpp
  test/SemaCXX/friend2.cpp
  test/SemaCXX/function-redecl-2.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16989.70025.patch
Type: text/x-patch
Size: 9970 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160901/91d64676/attachment.bin>


More information about the cfe-commits mailing list