https://github.com/Vipul-Cariappa created https://github.com/llvm/llvm-project/pull/218129
Regression was introduced in https://github.com/llvm/llvm-project/pull/178648 This is required for the 23 release; the downstream tools CppInterOp & Cppyy will fail otherwise. cc @vgvassilev >From 2efd52904481ebcb74c932f4e35f22a38a8e7e7a Mon Sep 17 00:00:00 2001 From: Vipul Cariappa <[email protected]> Date: Fri, 21 Aug 2026 23:23:37 +0530 Subject: [PATCH] [clang-repl] Don't double-remove extern "C" decls from the IdResolver Regression was introduced in https://github.com/llvm/llvm-project/pull/178648 --- clang/lib/Interpreter/IncrementalParser.cpp | 4 +- .../Interpreter/extern-c-error-recovery.cpp | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 clang/test/Interpreter/extern-c-error-recovery.cpp diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index 59018907056b8..edf528e76a15b 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -235,7 +235,9 @@ void IncrementalParser::CleanUpPTU(TranslationUnitDecl *MostRecentTU) { } for (NamedDecl *D : NamedDeclsToRemove) { List.remove(D); - S.IdResolver.RemoveDecl(D); + if (D->getDeclName().getFETokenInfo() && !D->getLangOpts().ObjC && + !D->getLangOpts().CPlusPlus) + S.IdResolver.RemoveDecl(D); } } } diff --git a/clang/test/Interpreter/extern-c-error-recovery.cpp b/clang/test/Interpreter/extern-c-error-recovery.cpp new file mode 100644 index 0000000000000..20b5223700007 --- /dev/null +++ b/clang/test/Interpreter/extern-c-error-recovery.cpp @@ -0,0 +1,63 @@ +// REQUIRES: host-supports-jit +// RUN: cat %s | clang-repl > %t.out 2>&1 +// RUN: FileCheck %s --input-file=%t.out +// RUN: FileCheck %s --check-prefix=NEGATIVE --input-file=%t.out + +// An input that declares something with C language linkage and then fails must +// not take the interpreter down with it. + +extern "C" int printf(const char *, ...); + +// An error in the body of an extern "C" function definition. +extern "C" void f1() { undeclared_thing; } +// CHECK-DAG: error: use of undeclared identifier 'undeclared_thing' +printf("alive %d\n", 1); +// CHECK-DAG: alive 1 + +// The same, written as an `extern "C" { ... }` block. +extern "C" { void f2() { undeclared_thing; } } +printf("alive %d\n", 2); +// CHECK-DAG: alive 2 + +// An extern "C" *variable* whose initializer fails: variables are registered +// with the ExternCContext by a different Sema path than functions. +extern "C" int v1 = undeclared_thing; +printf("alive %d\n", 3); +// CHECK-DAG: alive 3 + +// A deleted destructor reached through a wrapper -- the shape CppInterOp's +// generated destructor wrappers hit. +class D { public: ~D() = delete; }; +extern "C" void g(D *p) { delete p; } +// CHECK-DAG: error: attempt to use a deleted function +printf("alive %d\n", 4); +// CHECK-DAG: alive 4 + +// A block-scope `extern` inside an extern "C" function is registered with the +// ExternCContext but is already off the IdResolver by the time CleanUpPTU runs, +// because its own scope popped while the input was still being parsed. Removing +// it again therefore does not just fail to find it: with assertions off it +// clears the identifier's chain out from under whatever else is on it. +extern "C" void h1() { extern int fresh; undeclared_thing; } int fresh = 1; +printf("alive %d\n", 5); +// CHECK-DAG: alive 5 + +// Surviving is not enough: the discarded PTU must leave nothing behind, so the +// very same names have to be definable afterwards and the definitions have to +// be the ones that run. +extern "C" void f1() { printf("f1 ran\n"); } +extern "C" void f2() { printf("f2 ran\n"); } +extern "C" int v1 = 5; +f1(); +f2(); +printf("v1 %d\n", v1); +// CHECK-DAG: f1 ran +// CHECK-DAG: f2 ran +// CHECK-DAG: v1 5 + +// Nothing anywhere in the session may claim the recovered definitions clash +// with what the discarded inputs left behind. +// NEGATIVE-NOT: error: redefinition +// NEGATIVE-NOT: error: conflicting types + +%quit _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
