-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Add source range to 'use of undeclared identifier' diagnostics #117671
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
Conversation
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesFull diff: https://github.com/llvm/llvm-project/pull/117671.diff 1 Files Affected:
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6c7472ce92703b..cf3cc900f365b2 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2351,20 +2351,23 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
}
}
-static void emitEmptyLookupTypoDiagnostic(
- const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS,
- DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args,
- unsigned DiagnosticID, unsigned DiagnosticSuggestID) {
+static void emitEmptyLookupTypoDiagnostic(const TypoCorrection &TC,
+ Sema &SemaRef, const CXXScopeSpec &SS,
+ const DeclarationNameInfo &Typo,
+ ArrayRef<Expr *> Args,
+ unsigned DiagnosticID,
+ unsigned DiagnosticSuggestID) {
DeclContext *Ctx =
SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false);
if (!TC) {
// Emit a special diagnostic for failed member lookups.
// FIXME: computing the declaration context might fail here (?)
if (Ctx)
- SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
- << SS.getRange();
+ SemaRef.Diag(Typo.getLoc(), diag::err_no_member)
+ << Typo.getName() << Ctx << Typo.getSourceRange();
else
- SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
+ SemaRef.Diag(Typo.getLoc(), DiagnosticID)
+ << Typo.getName() << Typo.getSourceRange();
return;
}
@@ -2375,12 +2378,14 @@ static void emitEmptyLookupTypoDiagnostic(
? diag::note_implicit_param_decl
: diag::note_previous_decl;
if (!Ctx)
- SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo,
+ SemaRef.diagnoseTypo(TC,
+ SemaRef.PDiag(DiagnosticSuggestID) << Typo.getName(),
SemaRef.PDiag(NoteID));
else
- SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
- << Typo << Ctx << DroppedSpecifier
- << SS.getRange(),
+ SemaRef.diagnoseTypo(TC,
+ SemaRef.PDiag(diag::err_no_member_suggest)
+ << Typo.getName() << Ctx << DroppedSpecifier
+ << SS.getRange(),
SemaRef.PDiag(NoteID));
}
@@ -2448,13 +2453,14 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
TemplateArgumentListInfo *ExplicitTemplateArgs,
ArrayRef<Expr *> Args, DeclContext *LookupCtx,
TypoExpr **Out) {
- DeclarationName Name = R.getLookupName();
+ const DeclarationNameInfo &NameInfo = R.getLookupNameInfo();
unsigned diagnostic = diag::err_undeclared_var_use;
unsigned diagnostic_suggest = diag::err_undeclared_var_use_suggest;
- if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
- Name.getNameKind() == DeclarationName::CXXLiteralOperatorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
+ if (DeclarationName::NameKind Kind = NameInfo.getName().getNameKind();
+ Kind == DeclarationName::CXXOperatorName ||
+ Kind == DeclarationName::CXXLiteralOperatorName ||
+ Kind == DeclarationName::CXXConversionFunctionName) {
diagnostic = diag::err_undeclared_use;
diagnostic_suggest = diag::err_undeclared_use_suggest;
}
@@ -2506,13 +2512,12 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// We didn't find anything, so try to correct for a typo.
TypoCorrection Corrected;
if (S && Out) {
- SourceLocation TypoLoc = R.getNameLoc();
assert(!ExplicitTemplateArgs &&
"Diagnosing an empty lookup with explicit template args!");
*Out = CorrectTypoDelayed(
R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
[=](const TypoCorrection &TC) {
- emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args,
+ emitEmptyLookupTypoDiagnostic(TC, *this, SS, NameInfo, Args,
diagnostic, diagnostic_suggest);
},
nullptr, CTK_ErrorRecovery, LookupCtx);
@@ -2522,8 +2527,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S,
&SS, CCC, CTK_ErrorRecovery, LookupCtx))) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
- bool DroppedSpecifier =
- Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr;
+ bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
+ NameInfo.getAsString() == CorrectedStr;
R.setLookupName(Corrected.getCorrection());
bool AcceptableWithRecovery = false;
@@ -2591,12 +2596,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
? diag::note_implicit_param_decl
: diag::note_previous_decl;
if (SS.isEmpty())
- diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name,
+ diagnoseTypo(Corrected,
+ PDiag(diagnostic_suggest)
+ << NameInfo.getName() << NameInfo.getSourceRange(),
PDiag(NoteID), AcceptableWithRecovery);
else
- diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest)
- << Name << computeDeclContext(SS, false)
- << DroppedSpecifier << SS.getRange(),
+ diagnoseTypo(Corrected,
+ PDiag(diag::err_no_member_suggest)
+ << NameInfo.getName() << computeDeclContext(SS, false)
+ << DroppedSpecifier << SS.getRange(),
PDiag(NoteID), AcceptableWithRecovery);
// Tell the callee whether to try to recover.
@@ -2609,13 +2617,13 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// FIXME: computing the declaration context might fail here (?)
if (!SS.isEmpty()) {
Diag(R.getNameLoc(), diag::err_no_member)
- << Name << computeDeclContext(SS, false)
- << SS.getRange();
+ << NameInfo.getName() << computeDeclContext(SS, false) << SS.getRange();
return true;
}
// Give up, we can't recover.
- Diag(R.getNameLoc(), diagnostic) << Name;
+ Diag(R.getNameLoc(), diagnostic)
+ << NameInfo.getName() << NameInfo.getSourceRange();
return true;
}
|
f1e85ee
to
1d77f36
Compare
I knew there was something oddly familiar about this: https://reviews.llvm.org/D150191?id=521215 🤦♂️ |
Can you add a description? Maybe a changelog |
✅ With the latest revision this PR passed the C/C++ code formatter. |
It's the same problem again. For this code: #define F(x) x + 1
#define G(x) F(x) + 2
#define ADD(x,y) G(x) + y
#define LEVEL4(x) ADD(p,x)
#define LEVEL3(x) LEVEL4(x)
#define LEVEL2(x) LEVEL3(x)
#define LEVEL1(x) LEVEL2(x)
int a = LEVEL1(b); The previous output was:
and we now print:
but this is not a bug introduced by the changes, rather, the newly supplied (valid!) source ranges now get taken into account in |
Yeah, I think we need to solve that before moving forward with the changes, which is why this keeps not being improved. (It always seems to come back to bite us when we decide that invalid source locations are an in-band indicator of anything.) |
This is the best version I could come up with. Other than that, the code as it is seems to do what is advertised, i.e. the new output is the desired output. |
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.
Generally speaking, this looks like it's heading in the right direction.
In rangeInsideSameMacroArgExpansion, check the given Ranges instead of the SpellingRanges.
Ping |
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!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/20492 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/14695 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/195/builds/7799 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/197/builds/4179 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/141/builds/8000 Here is the relevant piece of the build log for the reference
|
No description provided.