[clang] [clang] Disable missing definition warning on pure virtual functions (PR #74510)

Charalampos Mitrodimas via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 6 00:34:31 PST 2023


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 <charmitro at 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 <charmitro at 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 828dd10e3d6db..10dce199b9fd1 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 d768bb72e07c0..a034de0697b2b 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 0000000000000..d188adc9ed034
--- /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 at -1 {{forward declaration of template entity is here}}
+    // expected-note at -2 {{forward declaration of template entity is here}}
+    // expected-note at -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 at -1 {{instantiation of function 'non_pure_virtual_function::B<int>::bar' required here, but no definition is available}}
+// expected-warning at -2 {{instantiation of function 'non_pure_virtual_function::B<int>::bar' required here, but no definition is available}}
+// expected-note at -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 at -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 at -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 at -6 {{used here}}
+
+  public:
+    constexpr void bar(unsigned int) override { }
+  };
+
+  void test() {
+    auto t = D<int>();
+    t.foo(0);
+  }
+};



More information about the cfe-commits mailing list