https://github.com/charmitro updated 
https://github.com/llvm/llvm-project/pull/74510

>From 83d29e896b7ae0b5b259cbf179143e526dc37b1c Mon Sep 17 00:00:00 2001
From: Charalampos Mitrodimas <charmi...@posteo.net>
Date: Tue, 5 Dec 2023 11:46:56 +0200
Subject: [PATCH] [clang] Disable missing definition warning on pure virtual
 functions

Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes #74016

Signed-off-by: Charalampos Mitrodimas <charmi...@posteo.net>
---
 clang/docs/ReleaseNotes.rst                   |  3 ++
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  3 +-
 .../instantiate-pure-virtual-function.cpp     | 48 +++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 828dd10e3d6db9..10dce199b9fd16 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -514,6 +514,9 @@ Improvements to Clang's time-trace
 
 Bug Fixes in This Version
 -------------------------
+- Clang's ``-Wundefined-func-template`` no longer warns on pure virtual
+  functions.
+  (`#74016 <https://github.com/llvm/llvm-project/issues/74016>`_)
 - Fixed an issue where a class template specialization whose declaration is
   instantiated in one module and whose definition is instantiated in another
   module may end up with members associated with the wrong declaration of the
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index d768bb72e07c09..a034de0697b2b7 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4952,7 +4952,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
         std::make_pair(Function, PointOfInstantiation));
     } else if (TSK == TSK_ImplicitInstantiation) {
       if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
-          !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
+          !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc()) &&
+          !Function->isPure()) {
         Diag(PointOfInstantiation, diag::warn_func_template_missing)
           << Function;
         Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
diff --git a/clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp 
b/clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp
new file mode 100644
index 00000000000000..d188adc9ed034e
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-func-template %s
+
+namespace GH74016 {
+  template <typename T> class B {
+  public:
+    constexpr void foo(const T &) { bar(1); }
+    virtual constexpr void bar(unsigned int) = 0;
+  };
+
+  template <typename T> class D : public B<T> {
+  public:
+    constexpr void bar(unsigned int) override {}
+  };
+
+  void test() {
+    auto t = D<int>();
+    t.foo(0);
+  }
+};
+
+namespace non_pure_virtual_function {
+  template <typename T> class B {
+  public:
+    constexpr void foo(const T &) { bar(1); }
+
+    virtual constexpr void bar(unsigned int); // expected-warning {{inline 
function 'non_pure_virtual_function::B<int>::bar' is not defined}}
+    // expected-note@-1 {{forward declaration of template entity is here}}
+    // expected-note@-2 {{forward declaration of template entity is here}}
+    // expected-note@-3 {{forward declaration of template entity is here}}
+  };
+
+  template <typename T> class D : public B<T> { // expected-warning 
{{instantiation of function 'non_pure_virtual_function::B<int>::bar' required 
here, but no definition is available}}
+// expected-warning@-1 {{instantiation of function 
'non_pure_virtual_function::B<int>::bar' required here, but no definition is 
available}}
+// expected-warning@-2 {{instantiation of function 
'non_pure_virtual_function::B<int>::bar' required here, but no definition is 
available}}
+// expected-note@-3 {{add an explicit instantiation declaration to suppress 
this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly 
instantiated in another translation unit}}
+// expected-note@-4 {{add an explicit instantiation declaration to suppress 
this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly 
instantiated in another translation unit}}
+// expected-note@-5 {{add an explicit instantiation declaration to suppress 
this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly 
instantiated in another translation unit}}
+// expected-note@-6 {{used here}}
+
+  public:
+    constexpr void bar(unsigned int) override { }
+  };
+
+  void test() {
+    auto t = D<int>();
+    t.foo(0);
+  }
+};

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to