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

>From f60f12f8e4e8b70a8fdf2aa9398b94849a863fff 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 +
 clang/lib/Sema/SemaExpr.cpp                   |  2 +-
 .../instantiate-pure-virtual-function.cpp     | 67 +++++++++++++++++++
 3 files changed, 71 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 ce7599ad34beaf..858248f3cce896 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -531,6 +531,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/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 960f513d1111b2..43b266ec07dd35 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18931,7 +18931,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, 
FunctionDecl *Func,
   //   constant evaluated
   bool NeededForConstantEvaluation =
       isPotentiallyConstantEvaluatedContext(*this) &&
-      isImplicitlyDefinableConstexprFunction(Func);
+      isImplicitlyDefinableConstexprFunction(Func) && !Func->isPure();
 
   // Determine whether we require a function definition to exist, per
   // C++11 [temp.inst]p3:
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..caec42b6b77f95
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp
@@ -0,0 +1,67 @@
+// 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 call_pure_virtual_function_from_virtual {
+  template <typename T> class B {
+  public:
+    const void foo(const T &) { B::bar(1); } // expected-warning 
{{instantiation of function 
'call_pure_virtual_function_from_virtual::B<int>::bar' required here, but no 
definition is available}}
+    // expected-note@-1 {{add an explicit instantiation declaration to 
suppress this warning if 'call_pure_virtual_function_from_virtual::B<int>::bar' 
is explicitly instantiated in another translation unit}}
+    virtual const void bar(unsigned int) = 0; // expected-note {{forward 
declaration of template entity is here}}
+  };
+
+  template <typename T> class D : public B<T> {
+  public:
+    const void bar(unsigned int) override {}
+  };
+
+  void test() {
+    auto t = D<int>();
+    t.foo(0); // expected-note {{in instantiation of member function 
'call_pure_virtual_function_from_virtual::B<int>::foo' requested here}}
+  }
+};
+
+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