[clang] [clang][Sema] Improve error recovery for id-expressions referencing invalid decls (PR #81662)

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 23 23:25:42 PDT 2024


https://github.com/HighCommander4 updated https://github.com/llvm/llvm-project/pull/81662

>From 480cabcfeb42542746026bba753b4170e08bb8ae Mon Sep 17 00:00:00 2001
From: Nathan Ridge <zeratul976 at hotmail.com>
Date: Tue, 13 Feb 2024 12:26:17 -0500
Subject: [PATCH] [clang][Sema] Improve error recovery for id-expressions
 referencing invalid decls

Passing AcceptInvalidDecl=true to BuildDeclarationNameExpr() allows
the RecoveryExpr that's constructed to retain a DeclRefExpr pointing
to the invalid decl as a child, preserving information about the
reference for use by tools such as clangd.

Fixes https://github.com/clangd/clangd/issues/1820
---
 clang/lib/Sema/SemaExpr.cpp          | 6 +++++-
 clang/test/AST/ast-dump-recovery.cpp | 6 ++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2a0e86c37f1bfc..ee999646a3a218 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2928,7 +2928,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
     return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs);
   }
 
-  return BuildDeclarationNameExpr(SS, R, ADL);
+  return BuildDeclarationNameExpr(SS, R, ADL, /*AcceptInvalidDecl=*/true);
 }
 
 /// BuildQualifiedDeclarationNameExpr - Build a C++ qualified
@@ -3453,6 +3453,10 @@ ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
+  if (R.isSingleResult() && R.getFoundDecl()->isInvalidDecl()) {
+    return CreateRecoveryExpr(ULE->getBeginLoc(), ULE->getEndLoc(), {ULE});
+  }
+
   return ULE;
 }
 
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index cfb013585ad744..f628fa913da1e6 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -402,6 +402,7 @@ void returnInitListFromVoid() {
   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
 }
 
+void FuncTakingUnknown(Unknown);
 void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
   InvalidDecl + 1;
   // CHECK:      BinaryOperator {{.*}}
@@ -411,6 +412,11 @@ void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
   InvalidDecl();
   // CHECK:      CallExpr {{.*}}
   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
+  FuncTakingUnknown(InvalidDecl);
+  // CHECK:      CallExpr {{.*}} '<dependent type>'
+  // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} '<overloaded function type>'
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'InvalidDecl' 'int'
 }
 
 void RecoverToAnInvalidDecl() {



More information about the cfe-commits mailing list