https://github.com/charmitro updated https://github.com/llvm/llvm-project/pull/74510
>From 0348c138e5a4295d86defbe40259105b64703d13 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 | 4 ++ clang/lib/Sema/SemaExpr.cpp | 6 +- .../instantiate-pure-virtual-function.cpp | 67 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 28e8ddb3c41c3e..15738b3fa03739 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -346,6 +346,10 @@ 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 missing warnings when comparing mismatched enumeration constants in C (`#29217 <https://github.com/llvm/llvm-project/issues/29217>`). diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6b2eb245d58263..33f8a7fdb4d903 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18980,8 +18980,10 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, // Note that we skip the implicit instantiation of templates that are only // used in unused default arguments or by recursive calls to themselves. // This is formally non-conforming, but seems reasonable in practice. - bool NeedDefinition = !IsRecursiveCall && (OdrUse == OdrUseContext::Used || - NeededForConstantEvaluation); + bool NeedDefinition = + !IsRecursiveCall && + (OdrUse == OdrUseContext::Used || + (NeededForConstantEvaluation && !Func->isPureVirtual())); // C++14 [temp.expl.spec]p6: // If a template [...] is explicitly specialized then that specialization 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