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