Author: fogsong233
Date: 2026-03-01T09:06:53+01:00
New Revision: 5768ee2dcdad1bba9763361313ccce5641497033

URL: 
https://github.com/llvm/llvm-project/commit/5768ee2dcdad1bba9763361313ccce5641497033
DIFF: 
https://github.com/llvm/llvm-project/commit/5768ee2dcdad1bba9763361313ccce5641497033.diff

LOG: [clang-repl] fix CleanUpPTU by removing decl according to C implicitly 
FuncitonDecl. (#178648)

fix #171440

---------

Co-authored-by: Vassil Vassilev <[email protected]>

Added: 
    clang/test/Interpreter/incremental-c-implicit-error.c
    clang/test/Interpreter/incremental-c-implicit-undo.c

Modified: 
    clang/lib/Interpreter/IncrementalParser.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index bf08911e23533..1329391fd0904 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -13,11 +13,13 @@
 #include "IncrementalParser.h"
 #include "IncrementalAction.h"
 
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclContextInternals.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Error.h"
@@ -182,6 +184,29 @@ void IncrementalParser::CleanUpPTU(TranslationUnitDecl 
*MostRecentTU) {
     }
   }
 
+  ExternCContextDecl *ECCD = S.getASTContext().getExternCContextDecl();
+  if (StoredDeclsMap *Map = ECCD->getPrimaryContext()->getLookupPtr()) {
+    for (auto &&[Key, List] : *Map) {
+      DeclContextLookupResult R = List.getLookupResult();
+      llvm::SmallVector<NamedDecl *, 4> NamedDeclsToRemove;
+      for (NamedDecl *D : R) {
+        // Implicitly generated C decl is not attached to the current TU but
+        // lexically attached to the recent TU, so we need to check the lexical
+        // context.
+        DeclContext *LDC = D->getLexicalDeclContext();
+        while (LDC && !isa<TranslationUnitDecl>(LDC))
+          LDC = LDC->getLexicalParent();
+        TranslationUnitDecl *TopTU = cast_or_null<TranslationUnitDecl>(LDC);
+        if (TopTU == MostRecentTU)
+          NamedDeclsToRemove.push_back(D);
+      }
+      for (NamedDecl *D : NamedDeclsToRemove) {
+        List.remove(D);
+        S.IdResolver.RemoveDecl(D);
+      }
+    }
+  }
+
   // FIXME: We should de-allocate MostRecentTU
   for (Decl *D : MostRecentTU->decls()) {
     auto *ND = dyn_cast<NamedDecl>(D);

diff  --git a/clang/test/Interpreter/incremental-c-implicit-error.c 
b/clang/test/Interpreter/incremental-c-implicit-error.c
new file mode 100644
index 0000000000000..251fbb3f23c95
--- /dev/null
+++ b/clang/test/Interpreter/incremental-c-implicit-error.c
@@ -0,0 +1,18 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl -Xcc -x -Xcc c -Xcc -std=c17 -Xcc -fno-builtin 
2>&1 | FileCheck %s
+// RUN: cat %s | clang-repl -Xcc -x -Xcc c -Xcc -std=c17 -Xcc -fno-builtin 
-Xcc -O2 2>&1 | FileCheck %s
+// see https://github.com/llvm/llvm-project/issues/171440.
+
+a();
+// CHECK: error: call to undeclared function 'a'
+// CHECK: ISO C99 and later do not support implicit function declarations
+
+void a() { return; }
+// CHECK-NOT: error: conflicting types
+
+a();
+// CHECK-NOT: Symbols not found
+
+
+int x = 10;
+%quit

diff  --git a/clang/test/Interpreter/incremental-c-implicit-undo.c 
b/clang/test/Interpreter/incremental-c-implicit-undo.c
new file mode 100644
index 0000000000000..8bd594d85f70f
--- /dev/null
+++ b/clang/test/Interpreter/incremental-c-implicit-undo.c
@@ -0,0 +1,17 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl -Xcc -x -Xcc c -Xcc -std=c17 -Xcc -fno-builtin 
-Xcc -Wno-error=implicit-function-declaration 2>&1 | FileCheck %s
+// RUN: cat %s | clang-repl -Xcc -x -Xcc c -Xcc -std=c17 -Xcc -fno-builtin 
-Xcc -O2 -Xcc -Wno-error=implicit-function-declaration 2>&1 | FileCheck %s
+
+a();
+
+void a() { return; }
+// CHECK: error: conflicting types
+
+p();
+%undo
+
+void p() {  }
+// CHECK-NOT: error: conflicting types
+
+int x = 10;
+%quit


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to