[PATCH] D16579: Warn if friend function depends on template parameters.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon May 9 17:00:37 PDT 2016


rsmith added inline comments.

================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:1153
@@ +1152,3 @@
+def warn_non_template_friend : Warning<"friend declaration %q0 depends on "
+  "template parameter but is not a template function">,
+   InGroup<NonTemplateFriend>;
----------------
template function -> function template

================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:1155-1157
@@ +1154,5 @@
+   InGroup<NonTemplateFriend>;
+def note_non_template_friend : Note<"if this is intentional, add function "
+  "declaration to suppress the warning, if not - make sure the function "
+  "template has already been declared and use '<>'">;
+def note_befriend_template : Note<"to befriend a template specialization, "
----------------
Rather than this long conditional note, how about producing two notes here:

  note: declare function outside class template to suppress this warning
  note: use '<>' to befriend a template specialization

================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:1158-1159
@@ -1152,1 +1157,4 @@
+  "template has already been declared and use '<>'">;
+def note_befriend_template : Note<"to befriend a template specialization, "
+  "use '<>'">;
 
----------------
This note should also point out that you need to declare the function template prior to the class template.

================
Comment at: include/clang/Sema/Sema.h:9342
@@ +9341,3 @@
+  /// of proper templates, but they are needed for checks.
+  llvm::DenseSet<FunctionDecl *> FriendsOfTemplates;
+
----------------
This will produce diagnostics in a nondeterministic order, and you have no need of a set because there can never be any duplicates. Just use a `SmallVector`?

================
Comment at: include/clang/Sema/Sema.h:9342
@@ +9341,3 @@
+  /// of proper templates, but they are needed for checks.
+  llvm::DenseSet<FunctionDecl *> FriendsOfTemplates;
+
----------------
rsmith wrote:
> This will produce diagnostics in a nondeterministic order, and you have no need of a set because there can never be any duplicates. Just use a `SmallVector`?
You're missing serialization code for this for the PCH / preamble case.

================
Comment at: include/clang/Sema/Sema.h:9344-9345
@@ +9343,4 @@
+
+  /// \brief Check dependent friends functions for misinterpretation as template
+  /// ones.
+  void CheckDependentFriends();
----------------
friends -> friend
template ones -> function templates

================
Comment at: lib/Sema/SemaChecking.cpp:10468
@@ +10467,3 @@
+/// function types.
+class FunctionMatcher : public TypeVisitor<FunctionMatcher, bool> {
+  const Type *InstType;
----------------
This is a huge amount of complexity and maintenance burden for this check, and it still seems to some important cases wrong. Is there a simpler way we can get a largely-equivalent result? Or maybe we can just unconditionally produce both notes?

================
Comment at: lib/Sema/SemaChecking.cpp:10700
@@ +10699,2 @@
+  }
+}
----------------
`FriendsOfTemplates.clear()` here?

================
Comment at: lib/Sema/SemaDecl.cpp:8502-8507
@@ -8501,1 +8501,8 @@
 
+  if (isFriend && !NewFD->isInvalidDecl()) {
+    if (TemplateParamLists.empty() && !DC->isRecord() &&
+        !isFunctionTemplateSpecialization) {
+      FriendsOfTemplates.insert(NewFD);
+    }
+  }
+
----------------
This should also be conditioned on the function having a dependent type and this declaration not being a definition -- this will add all non-template friends to `FriendsOfTemplates`, whether they're friends of a class template or not.


http://reviews.llvm.org/D16579





More information about the cfe-commits mailing list