-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Improve the -Wundefined-func-template diagnostic note for invisible template functions #129031
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5386,12 +5386,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, | |
| PatternDef = nullptr; | ||
| } | ||
|
|
||
| // True is the template definition is unreachable, otherwise false. | ||
| bool Unreachable = false; | ||
| // FIXME: We need to track the instantiation stack in order to know which | ||
| // definitions should be visible within this instantiation. | ||
| if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function, | ||
| Function->getInstantiatedFromMemberFunction(), | ||
| PatternDecl, PatternDef, TSK, | ||
| /*Complain*/DefinitionRequired)) { | ||
| if (DiagnoseUninstantiableTemplate( | ||
| PointOfInstantiation, Function, | ||
| Function->getInstantiatedFromMemberFunction(), PatternDecl, | ||
| PatternDef, TSK, | ||
| /*Complain*/ DefinitionRequired, &Unreachable)) { | ||
| if (DefinitionRequired) | ||
| Function->setInvalidDecl(); | ||
| else if (TSK == TSK_ExplicitInstantiationDefinition || | ||
|
|
@@ -5416,11 +5419,18 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, | |
| if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && | ||
| !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) { | ||
| Diag(PointOfInstantiation, diag::warn_func_template_missing) | ||
| << Function; | ||
| Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); | ||
| if (getLangOpts().CPlusPlus11) | ||
| Diag(PointOfInstantiation, diag::note_inst_declaration_hint) | ||
| << Function; | ||
| << Function; | ||
| if (Unreachable) { | ||
ilya-biryukov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // FIXME: would be nice to mention which module the function template | ||
| // comes from. | ||
| Diag(PatternDecl->getLocation(), | ||
|
||
| diag::note_unreachable_template_decl); | ||
| } else { | ||
| Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); | ||
| if (getLangOpts().CPlusPlus11) | ||
| Diag(PointOfInstantiation, diag::note_inst_declaration_hint) | ||
| << Function; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // RUN: rm -rf %t | ||
|
||
| // RUN: split-file %s %t | ||
| // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -I%t \ | ||
| // RUN: -Wundefined-func-template \ | ||
| // RUN: -fimplicit-module-maps %t/main.cpp 2>&1 | grep "unreachable declaration of template entity is here" | ||
|
|
||
| // Note that the diagnostics are triggered when building the 'hoge' module, which is imported from the main file. | ||
| // The "-verify" flag doesn't work in this case. Instead, we grep the expected text to verify the test. | ||
|
|
||
| //--- shared_ptr2.h | ||
| #pragma once | ||
|
|
||
| template<class T> | ||
| void x() { } | ||
|
|
||
| //--- hoge.h | ||
| #pragma once | ||
|
|
||
| #include "shared_ptr2.h" | ||
|
|
||
| inline void f() { | ||
| x<int>(); | ||
| } | ||
|
|
||
| //--- module.modulemap | ||
| module hoge { | ||
| header "hoge.h" | ||
| } | ||
|
|
||
| module shared_ptr2 { | ||
| header "shared_ptr2.h" | ||
| } | ||
|
|
||
| //--- main.cpp | ||
| #include "hoge.h" | ||
|
|
||
| int main() { | ||
| f(); | ||
| } | ||
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 be talking about "visibility" for Clang header modules and reachability for C++20 modules?
I am a little fuzzy on the terminology, but I think there was some distinction between the two we are making for the users.
@ChuanqiXu9, could you advise on the correct wording 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.
Yeah, "unreachable" is a formal definition for C++20 modules. But it looks like the method to judge unreachable decl in this patch is the same for C++20 modules. So I feel it might be fine.
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.
Thanks! If you are okay with this, let's keep as is.
Just a follow-up question for a better understanding: I somehow thought we would only check for reachability (as opposed to visibility) only since C++20.
Or should we expect Clang to sometimes complain about reachability in C++17 and below with
-fmodulesenabled? (The added test uses C++20, but I believe it can also be C++17; but I'm not 100% sure)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 yes. Clang already does this — in
Sema::DiagnoseUninstantiableTemplate, when a reachable function definition is missing, Clang may emit a "missing-import" diagnostic.However, for this particular testcase, the issue is only triggered with the C++20 standard module feature
Yes, this aligns with my reading of the code. The same code is shared between header modules and C++20 modules.