-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[clang] Disable missing definition warning on pure virtual functions #74510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Disable missing definition warning on pure virtual functions #74510
Conversation
@llvm/pr-subscribers-clang Author: Charalampos Mitrodimas (charmitro) ChangesWarning '-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 Full diff: https://github.com/llvm/llvm-project/pull/74510.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index d768bb72e07c0..0850b2d64b632 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->isVirtualAsWritten()) {
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..7ae323343330e
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-func-template %s
+// expected-no-diagnostics
+
+namespace PR74016 {
+ 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);
+ }
+};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps needs a release note.
@@ -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->isVirtualAsWritten()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also check that it is pure? AFAIK isVirtualAsWritten
returns true for function marked explicitly virtual. There is also FunctionDecl::isPure()
to check that it is pure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-func-template %s | ||
// expected-no-diagnostics | ||
|
||
namespace PR74016 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we normally call them GH when a bug was filed as a GitHub issue.
namespace PR74016 { | |
namespace GH74016 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. I wasn't aware of this, thanks!
0ea96c4
to
0be0d65
Compare
@@ -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->isVirtualAsWritten() && !Function->isPure()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!Function->isVirtualAsWritten() && !Function->isPure()) { | |
!(Function->isVirtualAsWritten() && Function->isPure()) { |
Can you add a test to make sure non-pure virtual function still get diagnosed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After double-checking this, I think we should just check for !isPure()
and don't bother checking for isVirtualAsWritten()
at all since non-virtual functions cannot be pure. Also, for reference,
llvm-project/clang/include/clang/AST/Decl.h
Lines 2293 to 2295 in d6fbd96
/// Whether this virtual function is pure, i.e. makes the containing class | |
/// abstract. | |
bool isPure() const { return FunctionDeclBits.IsPure; } |
Code updated to match this. Also a test-case added to verify that non-pure virtual functions still get diagnosed.
0be0d65
to
1140e00
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
1140e00
to
5582cfa
Compare
Can you add a release note indicating #74016 was fixed? If you wanted to make a follow up {R to rename |
5582cfa
to
83d29e8
Compare
Thank you both for your review!
Release note added.
Yes, this could be helpful. I'll create a follow up PR for this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks
Any progress on this patch? As we discussed in #74016, we should make sure clang doesn't stop emitting the warning when the definition of a pure virtual function is actually needed. It seems to me that we shouldn't set |
e38ad9c
to
f60f12f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from a minor NFC nit with where we decide to do the check, this LGTM
clang/lib/Sema/SemaExpr.cpp
Outdated
@@ -18931,7 +18931,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, | |||
// constant evaluated | |||
bool NeededForConstantEvaluation = | |||
isPotentiallyConstantEvaluatedContext(*this) && | |||
isImplicitlyDefinableConstexprFunction(Func); | |||
isImplicitlyDefinableConstexprFunction(Func) && !Func->isPure(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how the function being pure relates to whether it's needed for constant evaluation. I think this should move down to NeedDefinition
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I concur, this does not make sense doing the check here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving it to NeedDefinition
silences the warnings of test call_pure_virtual_function_from_virtual
, where we still require warnings for it, as mentioned in #74016 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure the diagnostic makes sense in that case since it can never actually be called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank to @erichkeane I realized I am wrong, we can actually define a pure virtual function. So we do want to retain the diagnostic here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure why moving it down silences the diagnostic, I would think doing (OdrUse == OdrUseContext::Used || NeededForConstantEvaluation || !Func->isPure())
should work.
Can you explain in more detail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're actually right.
I don't really recall what I was entering back when I was developing it, but it should work now.
f60f12f
to
7961a90
Compare
✅ With the latest revision this PR passed the Python code formatter. |
7961a90
to
89eb978
Compare
958ba59
to
c0ef5a0
Compare
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 llvm#74016 Signed-off-by: Charalampos Mitrodimas <[email protected]>
c0ef5a0
to
0348c13
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Do you need someone to land this on your behalf?
I don't have commit rights. If I remember correctly from when LLVM used Phabricator (reviews.llvm.org) you'd need my name & e-address. If that's so, |
…lvm#74510) 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 llvm#74016 (cherry picked from commit 0c92f86) Conflicts: clang/docs/ReleaseNotes.rst
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