Bug#1147122: llvm-toolchain-18: FTBFS against python 3.15rc2 and other problems

Maximiliano Curia maxy at debian.org
Mon Sep 7 22:24:17 BST 2026


Package: src:llvm-toolchain-18
Version: 1:18.1.8-20
User: debian-python at lists.debian.org
Usertags: python3.15
Tags: patch, ftbfs, forky, sid
Severity: serious

Hi!

While rebuilding the python related packages against the Python 3.15rc2
version we found that llvm-toolchain-18 fails to build from source [1].
It actually fails to build in general, regardless of Python 3.15, so
setting the severity to serious.

To fix the issues I had to apply a number of upstream patches to handle
kernel changes, cmake changes, gcc16 changes, python 3.14 and 3.15
changes.

On top of this, I also had to update some packaging tooling and
configuration. I'm attaching the debdiff including all the necessary
changes to get the package to build successfully.

I've applied the upstream fix in the sandbox [2] to verify that it
builds successfully, please apply the patch to get llvm-toolchain-18
back to build from source.

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/artifact/4372219/
[2]: https://debusine.debian.net/debian/r-python-python3.15/

-- 
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
-------------- next part --------------
diff -Nru llvm-toolchain-18-18.1.8/debian/changelog llvm-toolchain-18-18.1.8/debian/changelog
--- llvm-toolchain-18-18.1.8/debian/changelog	2025-11-08 14:36:04.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/changelog	2026-01-31 19:38:31.000000000 +0100
@@ -1,3 +1,31 @@
+llvm-toolchain-18 (1:18.1.8-20.1) UNRELEASED; urgency=medium
+
+  [ Igor Luppi <igor.luppi at canonical.com> ]
+  * d/llvm-X.Y-tools.bcep.in: fix bcep exception pattern (LP: #2138890).
+
+  [ Matthias Klose ]
+  * d/llvm-X.Y-tools.bcep.in: Fix Python 3.14 byte compilation by adding
+    an exception for shtest-encoding.py test file containing non-UTF-8
+    characters (Igor Luppi). LP: #2138890.
+
+  [ Maximiliano Curia ]
+  * Cherry-pick PR: #194116 and #219511 to remove linux/scc.h usage in
+    compiler-rt.
+  * Cherry-pick PR: #90517 and #197215 to fix Clang build and parsing
+    with GCC 16 libstdc++ headers.
+  * Cherry-pick PR: #83431, #82359, #86577, #86742, and #90845 to implement
+    __builtin_{clzg,ctzg,popcountg} builtins required by GCC 16 libstdc++.
+  * Cherry-pick PR: #210496 to skip host target exports on baremetal/wasm
+    builds with CMake 4.
+  * Cherry-pick PR: #131214 to fix race condition in opt-viewer demangler
+    with Python 3.14/3.15.
+  * Update cmake_minimum_required in qualify-clang.sh and
+    integration-test-suite for CMake 4.x compatibility.
+  * d/tests/control: Add python3 to test dependencies for python3-lldb and
+    python3-clang tests.
+
+ -- Gianfranco Costamagna <locutusofborg at debian.org>  Sat, 31 Jan 2026 19:38:31 +0100
+
 llvm-toolchain-18 (1:18.1.8-20) unstable; urgency=medium
 
   [ Matthias Klose ]
diff -Nru llvm-toolchain-18-18.1.8/debian/llvm-X.Y-tools.bcep.in llvm-toolchain-18-18.1.8/debian/llvm-X.Y-tools.bcep.in
--- llvm-toolchain-18-18.1.8/debian/llvm-X.Y-tools.bcep.in	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/llvm-X.Y-tools.bcep.in	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1 @@
+file|3.1-|/usr/lib/llvm- at LLVM_VERSION@/build/utils/lit/tests/shtest-encoding.py
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/clang-197215.patch llvm-toolchain-18-18.1.8/debian/patches/clang-197215.patch
--- llvm-toolchain-18-18.1.8/debian/patches/clang-197215.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/clang-197215.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,42 @@
+From ac3c588739a09ebb0f80a22ee10282592d858b47 Mon Sep 17 00:00:00 2001
+From: Corentin Jabot <corentinjabot at gmail.com>
+Date: Wed, 13 May 2026 11:38:52 +0200
+Subject: [PATCH] [Clang] Evaluate concepts in their declaration context. (#197215)
+
+Concepts appearing in a constraint expression of a class member had
+access to both `this` and the private member of the class.
+
+This changes fixes that by setting the concext to that of the context
+before evaluation of its constraint expression.
+
+This is done after we have substituted the template argument.
+
+Code in `Sema::isThisOutsideMemberFunctionBody` that no longer seems
+useful is renoved as it was interefering with this change.
+
+This is not an implementation of CWG2589 - at least not a complete one,
+as we still check access when doing substitution in the parameter
+mapping.
+
+Fixes #115838
+Fixes #194803
+---
+ clang/lib/Sema/SemaExprCXX.cpp | 5 -----
+ 1 file changed, 5 deletions(-)
+
+Index: llvm-test-quilt/clang/lib/Sema/SemaExprCXX.cpp
+===================================================================
+--- llvm-test-quilt.orig/clang/lib/Sema/SemaExprCXX.cpp
++++ llvm-test-quilt/clang/lib/Sema/SemaExprCXX.cpp
+@@ -1443,11 +1443,6 @@ void Sema::MarkThisReferenced(CXXThisExp
+ }
+ 
+ bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
+-  // If we're outside the body of a member function, then we'll have a specified
+-  // type for 'this'.
+-  if (CXXThisTypeOverride.isNull())
+-    return false;
+-
+   // Determine whether we're looking into a class that's currently being
+   // defined.
+   CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl();
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/clang-83431.patch llvm-toolchain-18-18.1.8/debian/patches/clang-83431.patch
--- llvm-toolchain-18-18.1.8/debian/patches/clang-83431.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/clang-83431.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,313 @@
+Index: llvm-test-build/clang/include/clang/Basic/Builtins.def
+===================================================================
+--- llvm-test-build.orig/clang/include/clang/Basic/Builtins.def
++++ llvm-test-build/clang/include/clang/Basic/Builtins.def
+@@ -685,6 +685,10 @@ BUILTIN(__builtin_alloca_with_align_unin
+ BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
+ BUILTIN(__builtin_nondeterministic_value, "v.", "nt")
+ 
++BUILTIN(__builtin_clzg , "i."   , "nctE")
++BUILTIN(__builtin_ctzg , "i."   , "nctE")
++BUILTIN(__builtin_popcountg , "i."   , "nctE")
++
+ BUILTIN(__builtin_elementwise_abs, "v.", "nct")
+ BUILTIN(__builtin_elementwise_bitreverse, "v.", "nct")
+ BUILTIN(__builtin_elementwise_max, "v.", "nct")
+Index: llvm-test-build/clang/include/clang/Basic/DiagnosticSemaKinds.td
+===================================================================
+--- llvm-test-build.orig/clang/include/clang/Basic/DiagnosticSemaKinds.td
++++ llvm-test-build/clang/include/clang/Basic/DiagnosticSemaKinds.td
+@@ -11954,7 +11954,9 @@ def err_builtin_invalid_arg_type: Error
+   "pointer to a valid matrix element type|"
+   "signed integer or floating point type|vector type|"
+   "floating point type|"
+-  "vector of integers}1 (was %2)">;
++  "vector of integers|"
++  "unsigned integer|"
++  "'int'}1 (was %2)">;
+ 
+ def err_builtin_matrix_disabled: Error<
+   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
+Index: llvm-test-build/clang/lib/AST/ExprConstant.cpp
+===================================================================
+--- llvm-test-build.orig/clang/lib/AST/ExprConstant.cpp
++++ llvm-test-build/clang/lib/AST/ExprConstant.cpp
+@@ -12289,6 +12289,7 @@ bool IntExprEvaluator::VisitBuiltinCallE
+   case Builtin::BI__builtin_clzl:
+   case Builtin::BI__builtin_clzll:
+   case Builtin::BI__builtin_clzs:
++  case Builtin::BI__builtin_clzg:
+   case Builtin::BI__lzcnt16: // Microsoft variants of count leading-zeroes
+   case Builtin::BI__lzcnt:
+   case Builtin::BI__lzcnt64: {
+@@ -12296,14 +12297,28 @@ bool IntExprEvaluator::VisitBuiltinCallE
+     if (!EvaluateInteger(E->getArg(0), Val, Info))
+       return false;
+ 
+-    // When the argument is 0, the result of GCC builtins is undefined, whereas
+-    // for Microsoft intrinsics, the result is the bit-width of the argument.
+-    bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
+-                           BuiltinOp != Builtin::BI__lzcnt &&
+-                           BuiltinOp != Builtin::BI__lzcnt64;
++    std::optional<APSInt> Fallback;
++    if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
++      APSInt FallbackTemp;
++      if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
++        return false;
++      Fallback = FallbackTemp;
++    }
+ 
+-    if (ZeroIsUndefined && !Val)
+-      return Error(E);
++    if (!Val) {
++      if (Fallback)
++        return Success(*Fallback, E);
++
++      // When the argument is 0, the result of GCC builtins is undefined,
++      // whereas for Microsoft intrinsics, the result is the bit-width of the
++      // argument.
++      bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
++                             BuiltinOp != Builtin::BI__lzcnt &&
++                             BuiltinOp != Builtin::BI__lzcnt64;
++
++      if (ZeroIsUndefined)
++        return Error(E);
++    }
+ 
+     return Success(Val.countl_zero(), E);
+   }
+@@ -12345,12 +12360,26 @@ bool IntExprEvaluator::VisitBuiltinCallE
+   case Builtin::BI__builtin_ctz:
+   case Builtin::BI__builtin_ctzl:
+   case Builtin::BI__builtin_ctzll:
+-  case Builtin::BI__builtin_ctzs: {
++  case Builtin::BI__builtin_ctzs:
++  case Builtin::BI__builtin_ctzg: {
+     APSInt Val;
+     if (!EvaluateInteger(E->getArg(0), Val, Info))
+       return false;
+-    if (!Val)
++
++    std::optional<APSInt> Fallback;
++    if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
++      APSInt FallbackTemp;
++      if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
++        return false;
++      Fallback = FallbackTemp;
++    }
++
++    if (!Val) {
++      if (Fallback)
++        return Success(*Fallback, E);
++
+       return Error(E);
++    }
+ 
+     return Success(Val.countr_zero(), E);
+   }
+@@ -12461,6 +12490,7 @@ bool IntExprEvaluator::VisitBuiltinCallE
+   case Builtin::BI__builtin_popcount:
+   case Builtin::BI__builtin_popcountl:
+   case Builtin::BI__builtin_popcountll:
++  case Builtin::BI__builtin_popcountg:
+   case Builtin::BI__popcnt16: // Microsoft variants of popcount
+   case Builtin::BI__popcnt:
+   case Builtin::BI__popcnt64: {
+Index: llvm-test-build/clang/lib/CodeGen/CGBuiltin.cpp
+===================================================================
+--- llvm-test-build.orig/clang/lib/CodeGen/CGBuiltin.cpp
++++ llvm-test-build/clang/lib/CodeGen/CGBuiltin.cpp
+@@ -3130,36 +3130,66 @@ RValue CodeGenFunction::EmitBuiltinExpr(
+   case Builtin::BI__builtin_ctzs:
+   case Builtin::BI__builtin_ctz:
+   case Builtin::BI__builtin_ctzl:
+-  case Builtin::BI__builtin_ctzll: {
+-    Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
++  case Builtin::BI__builtin_ctzll:
++  case Builtin::BI__builtin_ctzg: {
++    bool HasFallback = BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_ctzg &&
++                       E->getNumArgs() > 1;
++
++    Value *ArgValue =
++        HasFallback ? EmitScalarExpr(E->getArg(0))
++                    : EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
+ 
+     llvm::Type *ArgType = ArgValue->getType();
+     Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+ 
+     llvm::Type *ResultType = ConvertType(E->getType());
+-    Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
++    Value *ZeroUndef =
++        Builder.getInt1(HasFallback || getTarget().isCLZForZeroUndef());
+     Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
+     if (Result->getType() != ResultType)
+-      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+-                                     "cast");
+-    return RValue::get(Result);
++      Result =
++          Builder.CreateIntCast(Result, ResultType, /*isSigned*/ false, "cast");
++    if (!HasFallback)
++      return RValue::get(Result);
++
++    Value *Zero = Constant::getNullValue(ArgType);
++    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
++    Value *FallbackValue = EmitScalarExpr(E->getArg(1));
++    Value *ResultOrFallback =
++        Builder.CreateSelect(IsZero, FallbackValue, Result, "ctzg");
++    return RValue::get(ResultOrFallback);
+   }
+   case Builtin::BI__builtin_clzs:
+   case Builtin::BI__builtin_clz:
+   case Builtin::BI__builtin_clzl:
+-  case Builtin::BI__builtin_clzll: {
+-    Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
++  case Builtin::BI__builtin_clzll:
++  case Builtin::BI__builtin_clzg: {
++    bool HasFallback = BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_clzg &&
++                       E->getNumArgs() > 1;
++
++    Value *ArgValue =
++        HasFallback ? EmitScalarExpr(E->getArg(0))
++                    : EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
+ 
+     llvm::Type *ArgType = ArgValue->getType();
+     Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+ 
+     llvm::Type *ResultType = ConvertType(E->getType());
+-    Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
++    Value *ZeroUndef =
++        Builder.getInt1(HasFallback || getTarget().isCLZForZeroUndef());
+     Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
+     if (Result->getType() != ResultType)
+-      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+-                                     "cast");
+-    return RValue::get(Result);
++      Result =
++          Builder.CreateIntCast(Result, ResultType, /*isSigned*/ false, "cast");
++    if (!HasFallback)
++      return RValue::get(Result);
++
++    Value *Zero = Constant::getNullValue(ArgType);
++    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
++    Value *FallbackValue = EmitScalarExpr(E->getArg(1));
++    Value *ResultOrFallback =
++        Builder.CreateSelect(IsZero, FallbackValue, Result, "clzg");
++    return RValue::get(ResultOrFallback);
+   }
+   case Builtin::BI__builtin_ffs:
+   case Builtin::BI__builtin_ffsl:
+@@ -3219,7 +3249,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
+   case Builtin::BI__popcnt64:
+   case Builtin::BI__builtin_popcount:
+   case Builtin::BI__builtin_popcountl:
+-  case Builtin::BI__builtin_popcountll: {
++  case Builtin::BI__builtin_popcountll:
++  case Builtin::BI__builtin_popcountg: {
+     Value *ArgValue = EmitScalarExpr(E->getArg(0));
+ 
+     llvm::Type *ArgType = ArgValue->getType();
+@@ -3228,8 +3259,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
+     llvm::Type *ResultType = ConvertType(E->getType());
+     Value *Result = Builder.CreateCall(F, ArgValue);
+     if (Result->getType() != ResultType)
+-      Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+-                                     "cast");
++      Result =
++          Builder.CreateIntCast(Result, ResultType, /*isSigned*/ false, "cast");
+     return RValue::get(Result);
+   }
+   case Builtin::BI__builtin_unpredictable: {
+Index: llvm-test-build/clang/lib/Sema/SemaChecking.cpp
+===================================================================
+--- llvm-test-build.orig/clang/lib/Sema/SemaChecking.cpp
++++ llvm-test-build/clang/lib/Sema/SemaChecking.cpp
+@@ -2143,6 +2143,71 @@ static bool checkFPMathBuiltinElementTyp
+   return false;
+ }
+ 
++/// Checks that __builtin_popcountg was called with a single argument, which is
++/// an unsigned integer.
++static bool SemaBuiltinPopcountg(Sema &S, CallExpr *TheCall) {
++  if (checkArgCount(S, TheCall, 1))
++    return true;
++
++  ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));
++  if (ArgRes.isInvalid())
++    return true;
++
++  Expr *Arg = ArgRes.get();
++  TheCall->setArg(0, Arg);
++
++  QualType ArgTy = Arg->getType();
++
++  if (!ArgTy->isUnsignedIntegerType()) {
++    S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
++        << 1 << /*unsigned integer ty*/ 7 << ArgTy;
++    return true;
++  }
++  return false;
++}
++
++/// Checks that __builtin_{clzg,ctzg} was called with a first argument, which is
++/// an unsigned integer, and an optional second argument, which is promoted to
++/// an 'int'.
++static bool SemaBuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {
++  if (checkArgCountRange(S, TheCall, 1, 2))
++    return true;
++
++  ExprResult Arg0Res = S.DefaultLvalueConversion(TheCall->getArg(0));
++  if (Arg0Res.isInvalid())
++    return true;
++
++  Expr *Arg0 = Arg0Res.get();
++  TheCall->setArg(0, Arg0);
++
++  QualType Arg0Ty = Arg0->getType();
++
++  if (!Arg0Ty->isUnsignedIntegerType()) {
++    S.Diag(Arg0->getBeginLoc(), diag::err_builtin_invalid_arg_type)
++        << 1 << /*unsigned integer ty*/ 7 << Arg0Ty;
++    return true;
++  }
++
++  if (TheCall->getNumArgs() > 1) {
++    ExprResult Arg1Res = S.UsualUnaryConversions(TheCall->getArg(1));
++    if (Arg1Res.isInvalid())
++      return true;
++
++    Expr *Arg1 = Arg1Res.get();
++    TheCall->setArg(1, Arg1);
++
++    QualType Arg1Ty = Arg1->getType();
++
++    if (!Arg1Ty->isSpecificBuiltinType(BuiltinType::Int)) {
++      S.Diag(Arg1->getBeginLoc(), diag::err_builtin_invalid_arg_type)
++          << 2 << /*'int' ty*/ 8 << Arg1Ty;
++      return true;
++    }
++  }
++
++  return false;
++}
++
+ ExprResult
+ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
+                                CallExpr *TheCall) {
+@@ -2900,7 +2965,17 @@ Sema::CheckBuiltinFunctionCall(FunctionD
+            diag::err_hip_invalid_args_builtin_mangled_name);
+       return ExprError();
+     }
++    break;
+   }
++  case Builtin::BI__builtin_popcountg:
++    if (SemaBuiltinPopcountg(*this, TheCall))
++      return ExprError();
++    break;
++  case Builtin::BI__builtin_clzg:
++  case Builtin::BI__builtin_ctzg:
++    if (SemaBuiltinCountZeroBitsGeneric(*this, TheCall))
++      return ExprError();
++    break;
+   }
+ 
+   // Since the target specific builtins for each arch overlap, only check those
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/clang-90517.patch llvm-toolchain-18-18.1.8/debian/patches/clang-90517.patch
--- llvm-toolchain-18-18.1.8/debian/patches/clang-90517.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/clang-90517.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,171 @@
+From f061a395ffb78215a23e0f503e8ea121ee3b13ad Mon Sep 17 00:00:00 2001
+From: Krystian Stasiowski <sdkrystian at gmail.com>
+Date: Tue, 30 Apr 2024 14:23:02 -0400
+Subject: [PATCH] [Clang][Sema][Parse] Delay parsing of noexcept-specifiers in
+ friend function declarations (#90517)
+
+According to [class.mem.general] p8:
+> A complete-class context of a class (template) is a
+> - function body,
+> - default argument,
+> - default template argument,
+> - _noexcept-specifier_, or
+> - default member initializer
+>
+> within the member-specification of the class or class template.
+
+When testing #90152, it came to my attention that we do _not_ consider
+the _noexcept-specifier_ of a friend function declaration to be a
+complete-class context (something which the Microsoft standard library
+depends on). Although a comment states that this is "consistent with
+what other implementations do", the only other implementation that
+exhibits this behavior is GCC (MSVC and EDG both late-parse the
+_noexcept-specifier_).
+
+This patch changes _noexcept-specifiers_ of friend function declarations
+to be late parsed, which is in agreement with the standard & majority of
+implementations. Pre-#90152, our existing implementation falls "in
+between" the implementation consensus: within non-template classes, we
+would not find latter declared members (qualified and unqualified),
+while within class templates we would not find latter declared member
+when named with a unqualified name, we would find members named with a
+qualified name (even when lookup context is the current instantiation).
+Therefore, this _shouldn't_ be a breaking change -- any code that didn't
+compile will continue to not compile (since a _noexcept-specifier_ is
+not part of the deduction substitution
+loci (see [temp.deduct.general] p7), and any code which
+did compile should continue to do so.
+---
+ clang/include/clang/Sema/Sema.h      | 10 ++++----
+ clang/lib/Parse/ParseDecl.cpp        | 20 +++++++++++----
+ clang/lib/Sema/SemaDeclCXX.cpp       | 40 ++++++++++++++----------------
+ clang/lib/Sema/SemaExceptionSpec.cpp | 13 +++++-----
+ 4 files changed, 44 insertions(+), 39 deletions(-)
+
+--- a/clang/include/clang/Sema/Sema.h
++++ b/clang/include/clang/Sema/Sema.h
+@@ -6511,10 +6511,9 @@
+   /// parse an exception specification to work around a libstdc++ bug.
+   bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D);
+ 
+-  /// Add an exception-specification to the given member function
+-  /// (or member function template). The exception-specification was parsed
+-  /// after the method itself was declared.
+-  void actOnDelayedExceptionSpecification(Decl *Method,
++  /// Add an exception-specification to the given function (or function template).
++  /// The exception-specification was parsed after the function itself was declared.
++  void actOnDelayedExceptionSpecification(Decl *D,
+          ExceptionSpecificationType EST,
+          SourceRange SpecificationRange,
+          ArrayRef<ParsedType> DynamicExceptions,
+--- a/clang/lib/Parse/ParseDecl.cpp
++++ b/clang/lib/Parse/ParseDecl.cpp
+@@ -7154,11 +7154,16 @@
+ 
+       // Parse exception-specification[opt].
+       // FIXME: Per [class.mem]p6, all exception-specifications at class scope
+-      // should be delayed, including those for non-members (eg, friend
+-      // declarations). But only applying this to member declarations is
+-      // consistent with what other implementations do.
+-      bool Delayed = D.isFirstDeclarationOfMember() &&
+-                     D.isFunctionDeclaratorAFunctionDeclaration();
++      // We can also see a noexcept specifier in function declarations
++      // that are not methods.
++      bool Delayed = false;
++      switch (D.getContext()) {
++      case DeclaratorContext::Member:
++        Delayed = D.isFunctionDeclaratorAFunctionDeclaration();
++        break;
++      default:
++        break;
++      }
+       if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
+           GetLookAheadToken(0).is(tok::kw_noexcept) &&
+           GetLookAheadToken(1).is(tok::l_paren) &&
+--- a/clang/lib/Sema/SemaDeclCXX.cpp
++++ b/clang/lib/Sema/SemaDeclCXX.cpp
+@@ -19141,40 +19141,40 @@
+   }
+ }
+ 
+-void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
+-             ExceptionSpecificationType EST,
+-             SourceRange SpecificationRange,
+-             ArrayRef<ParsedType> DynamicExceptions,
+-             ArrayRef<SourceRange> DynamicExceptionRanges,
+-             Expr *NoexceptExpr) {
+-  if (!MethodD)
++void Sema::actOnDelayedExceptionSpecification(
++    Decl *D, ExceptionSpecificationType EST, SourceRange SpecificationRange,
++    ArrayRef<ParsedType> DynamicExceptions,
++    ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr) {
++  if (!D)
+     return;
+ 
+-  // Dig out the method we're referring to.
+-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD))
+-    MethodD = FunTmpl->getTemplatedDecl();
++  // Dig out the function we're referring to.
++  if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
++    D = FTD->getTemplatedDecl();
+ 
+-  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(MethodD);
+-  if (!Method)
++  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
++  if (!FD)
+     return;
+ 
+   // Check the exception specification.
+   llvm::SmallVector<QualType, 4> Exceptions;
+   FunctionProtoType::ExceptionSpecInfo ESI;
+-  checkExceptionSpecification(/*IsTopLevel*/true, EST, DynamicExceptions,
++  checkExceptionSpecification(/*IsTopLevel=*/true, EST, DynamicExceptions,
+                               DynamicExceptionRanges, NoexceptExpr, Exceptions,
+                               ESI);
+ 
+   // Update the exception specification on the function type.
+-  Context.adjustExceptionSpec(Method, ESI, /*AsWritten*/true);
++  Context.adjustExceptionSpec(FD, ESI, /*AsWritten=*/true);
+ 
+-  if (Method->isStatic())
+-    checkThisInStaticMemberFunctionExceptionSpec(Method);
+-
+-  if (Method->isVirtual()) {
+-    // Check overrides, which we previously had to delay.
+-    for (const CXXMethodDecl *O : Method->overridden_methods())
+-      CheckOverridingFunctionExceptionSpec(Method, O);
++  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
++    if (MD->isStatic())
++      checkThisInStaticMemberFunctionExceptionSpec(MD);
++
++    if (MD->isVirtual()) {
++      // Check overrides, which we previously had to delay.
++      for (const CXXMethodDecl *O : MD->overridden_methods())
++        CheckOverridingFunctionExceptionSpec(MD, O);
++    }
+   }
+ }
+ 
+--- a/clang/lib/Sema/SemaExceptionSpec.cpp
++++ b/clang/lib/Sema/SemaExceptionSpec.cpp
+@@ -258,13 +258,14 @@
+ }
+ 
+ static bool exceptionSpecNotKnownYet(const FunctionDecl *FD) {
+-  auto *MD = dyn_cast<CXXMethodDecl>(FD);
+-  if (!MD)
++  ExceptionSpecificationType EST =
++      FD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType();
++  if (EST == EST_Unparsed)
++    return true;
++  else if (EST != EST_Unevaluated)
+     return false;
+-
+-  auto EST = MD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType();
+-  return EST == EST_Unparsed ||
+-         (EST == EST_Unevaluated && MD->getParent()->isBeingDefined());
++  const DeclContext *DC = FD->getLexicalDeclContext();
++  return DC->isRecord() && cast<RecordDecl>(DC)->isBeingDefined();
+ }
+ 
+ static bool CheckEquivalentExceptionSpecImpl(
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/cmake-210496.patch llvm-toolchain-18-18.1.8/debian/patches/cmake-210496.patch
--- llvm-toolchain-18-18.1.8/debian/patches/cmake-210496.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/cmake-210496.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,90 @@
+From a04f87fdd9b59c6089bf731c669c6f149208363c Mon Sep 17 00:00:00 2001
+From: Haowei <haowei at google.com>
+Date: Mon, 20 Jul 2026 10:47:59 -0700
+Subject: [PATCH] Reapply "Skipping host target exports during cross-compilation" (#210496)
+
+Under CMake 4+, calling add_library(... SHARED IMPORTED) on a target
+platform that lacks dynamic linking support triggers a fatal error. This
+becomes an issue when building LLVM and runtimes for baremetal targets
+like armv6m-none-eabi. This patch adds the option
+"LLVM_OMIT_EXPORTS_FROM_CONFIG" in LLVM. When used in sub builds like
+LLVM runtimes, it makes CMake to skip including the LLVM and Clang
+exports. This mitigates the CMake 4 errors on baremetal runtimes.
+---
+ clang/cmake/modules/ClangConfig.cmake.in       |  7 +++++--
+ compiler-rt/cmake/Modules/CompilerRTUtils.cmake |  9 +++++++++
+ llvm/cmake/modules/LLVMConfig.cmake.in         |  2 +-
+ runtimes/CMakeLists.txt                        |  9 +++++++++
+ 4 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/clang/cmake/modules/ClangConfig.cmake.in b/clang/cmake/modules/ClangConfig.cmake.in
+index 5f67681649c6..1ae6a9340343 100644
+--- a/clang/cmake/modules/ClangConfig.cmake.in
++++ b/clang/cmake/modules/ClangConfig.cmake.in
+@@ -11,8 +11,11 @@ set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@")
+ set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@")
+ set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@")
+ 
+-# Provide all our library targets to users.
+- at CLANG_CONFIG_INCLUDE_EXPORTS@
++# Provide all our library targets to users. Skip when
++# LLVM_OMIT_EXPORTS_FROM_CONFIG flag is set.
++if(NOT LLVM_OMIT_EXPORTS_FROM_CONFIG)
++  @CLANG_CONFIG_INCLUDE_EXPORTS@
++endif()
+ 
+ # By creating clang-tablegen-targets here, subprojects that depend on Clang's
+ # tablegen-generated headers can always depend on this target whether building
+diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+index 25e7823716fc..9489cb038764 100644
+--- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
++++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+@@ -300,6 +300,15 @@ macro(load_llvm_config)
+       "You are not using the monorepo layout. This configuration is DEPRECATED.")
+   endif()
+ 
++  # Exports from LLVM and Clang may contain shared libraries. When targeting
++  # platforms that lack shared library support, importing such
++  # exports unrestrictedly will trigger an error. Set
++  # LLVM_OMIT_EXPORTS_FROM_CONFIG flag to skip importing these exports
++  # when the target platform does not support shared libraries.
++  get_property(HAS_SHARED_SUPPORT GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
++  if (NOT HAS_SHARED_SUPPORT)
++    set(LLVM_OMIT_EXPORTS_FROM_CONFIG ON)
++  endif()
+   find_package(LLVM HINTS "${LLVM_CMAKE_DIR}")
+   if (NOT LLVM_FOUND)
+      message(WARNING "UNSUPPORTED COMPILER-RT CONFIGURATION DETECTED: "
+diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in
+index 770a9caea322..2e6116b0d888 100644
+--- a/llvm/cmake/modules/LLVMConfig.cmake.in
++++ b/llvm/cmake/modules/LLVMConfig.cmake.in
+@@ -145,7 +145,7 @@ set(LLVM_ENABLE_SHARED_LIBS @BUILD_SHARED_LIBS@)
+ set(LLVM_DEFAULT_EXTERNAL_LIT "@LLVM_CONFIG_DEFAULT_EXTERNAL_LIT@")
+ set(LLVM_LIT_ARGS "@LLVM_LIT_ARGS@")
+ 
+-if(NOT TARGET LLVMSupport)
++if(NOT TARGET LLVMSupport AND NOT LLVM_OMIT_EXPORTS_FROM_CONFIG)
+   @LLVM_CONFIG_INCLUDE_EXPORTS@
+   @llvm_config_include_buildtree_only_exports@
+ endif()
+diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
+index 742334328fd3..d546c3f52382 100644
+--- a/runtimes/CMakeLists.txt
++++ b/runtimes/CMakeLists.txt
+@@ -45,6 +45,15 @@ function(runtime_register_component name)
+   set_property(GLOBAL APPEND PROPERTY SUB_COMPONENTS ${name})
+ endfunction()
+ 
++# Exports from LLVM and Clang may contain shared libraries. When targeting
++# platforms that lack shared library support, importing such
++# exports unrestrictedly will trigger an error. Set
++# LLVM_OMIT_EXPORTS_FROM_CONFIG flag to skip importing these exports
++# when the target platform does not support shared libraries.
++get_property(HAS_SHARED_SUPPORT GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
++if (NOT HAS_SHARED_SUPPORT)
++  set(LLVM_OMIT_EXPORTS_FROM_CONFIG ON)
++endif()
+ find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ find_package(Clang PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ 
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/integration-test-suite-cmake.diff llvm-toolchain-18-18.1.8/debian/patches/integration-test-suite-cmake.diff
--- llvm-toolchain-18-18.1.8/debian/patches/integration-test-suite-cmake.diff	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/integration-test-suite-cmake.diff	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,23 @@
+Description: Update cmake_minimum_required for CMake 4.x compatibility in integration-test-suite
+Author: Maximiliano Curia <maxy at debian.org>
+--- a/integration-test-suite/CMakeLists.txt
++++ b/integration-test-suite/CMakeLists.txt
+@@ -1,3 +1,3 @@
+-cmake_minimum_required(VERSION 3.4.3)
++cmake_minimum_required(VERSION 3.5)
+ 
+ message(STATUS "Checking for lit")
+--- a/integration-test-suite/tests/minimal_llvm_cmake.txt
++++ b/integration-test-suite/tests/minimal_llvm_cmake.txt
+@@ -6,3 +6,3 @@
+ 
+-cmake_minimum_required(VERSION 3.4.3)
++cmake_minimum_required(VERSION 3.5)
+ 
+--- a/integration-test-suite/tests/plugins_newpm.txt
++++ b/integration-test-suite/tests/plugins_newpm.txt
+@@ -13,3 +13,3 @@
+ 
+-cmake_minimum_required(VERSION 3.4.3)
++cmake_minimum_required(VERSION 3.5)
+ 
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/optrecord-131214.patch llvm-toolchain-18-18.1.8/debian/patches/optrecord-131214.patch
--- llvm-toolchain-18-18.1.8/debian/patches/optrecord-131214.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/optrecord-131214.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,54 @@
+From e0f8898e1d432ab4fdcaf353bf87a1d3cf36491a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
+Date: Wed, 2 Apr 2025 11:52:41 +0200
+Subject: [PATCH] Avoid a race condition in opt-viewer/optrecord (#131214)
+
+See https://bugzilla.redhat.com/2336915
+See https://reviews.llvm.org/D41784?id=
+See https://github.com/androm3da/optviewer-demo/issues/4#issuecomment-718787822
+
+Fixes https://github.com/llvm/llvm-project/issues/62403.
+
+The race condition happened when the demangler_proc was being set. The
+locking mechanism itself happened too late.
+
+This way, the lock always exists (to avoid a race when creating it) and
+is always used when *creating* demangler_proc.
+---
+ llvm/tools/opt-viewer/optrecord.py | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/llvm/tools/opt-viewer/optrecord.py b/llvm/tools/opt-viewer/optrecord.py
+index 9e2fc7cb553b..8014204a64f4 100644
+--- a/llvm/tools/opt-viewer/optrecord.py
++++ b/llvm/tools/opt-viewer/optrecord.py
+@@ -64,17 +64,19 @@ class Remark(yaml.YAMLObject):
+ 
+     default_demangler = "c++filt -n"
+     demangler_proc = None
++    demangler_lock = Lock()
+ 
+     @classmethod
+     def set_demangler(cls, demangler):
+         cls.demangler_proc = subprocess.Popen(
+             demangler.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE
+         )
+-        cls.demangler_lock = Lock()
+ 
+     @classmethod
+     def demangle(cls, name):
+         with cls.demangler_lock:
++            if not cls.demangler_proc:
++                cls.set_demangler(cls.default_demangler)
+             cls.demangler_proc.stdin.write((name + "\n").encode("utf-8"))
+             cls.demangler_proc.stdin.flush()
+             return cls.demangler_proc.stdout.readline().rstrip().decode("utf-8")
+@@ -323,8 +325,6 @@ def get_remarks(input_file, filter_=None):
+ def gather_results(filenames, num_jobs, should_print_progress, filter_=None):
+     if should_print_progress:
+         print("Reading YAML files...")
+-    if not Remark.demangler_proc:
+-        Remark.set_demangler(Remark.default_demangler)
+     remarks = optpmap.pmap(
+         get_remarks, filenames, num_jobs, should_print_progress, filter_
+     )
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/sanitizer-194116.patch llvm-toolchain-18-18.1.8/debian/patches/sanitizer-194116.patch
--- llvm-toolchain-18-18.1.8/debian/patches/sanitizer-194116.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/sanitizer-194116.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,38 @@
+From 3dc4fd6dd41100f051a63642f449b16324389c96 Mon Sep 17 00:00:00 2001
+From: cqwrteur <uwgghhbcad at gmail.com>
+Date: Sat, 25 Apr 2026 14:23:32 +0800
+Subject: [PATCH] [compiler-rt][sanitizer] Remove linux/scc.h (#194116)
+
+#194110
+
+Linux Kernel has removed scc.h header completely from the source code
+Therefore, we need to remove the usage in compiler-rt/sanitizer too.
+https://github.com/torvalds/linux/commit/64edfa65062dc4509ba75978116b2f6d392346f5#diff-1ca78e598a5041ee51ae795d168435afad598b82a7a0ce80f215993589b96c7c
+
+Without removing it, not only it breaks compiler-rt but also GCC build
+since GCC always builds libsanitizer for linux targets.
+
+After merging this we will need to cherry pick to GCC.
+---
+ compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+@@ -151,7 +151,6 @@
+ #include <linux/lp.h>
+ #include <linux/mroute.h>
+ #include <linux/mroute6.h>
+-#include <linux/scc.h>
+ #include <linux/serial.h>
+ #include <sys/msg.h>
+ #include <sys/ipc.h>
+@@ -517,8 +516,6 @@
+   unsigned struct_kbsentry_sz = sizeof(struct kbsentry);
+   unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo);
+   unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct);
+-  unsigned struct_scc_modem_sz = sizeof(struct scc_modem);
+-  unsigned struct_scc_stat_sz = sizeof(struct scc_stat);
+   unsigned struct_serial_multiport_struct_sz
+       = sizeof(struct serial_multiport_struct);
+   unsigned struct_serial_struct_sz = sizeof(struct serial_struct);
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/sanitizer-219511.patch llvm-toolchain-18-18.1.8/debian/patches/sanitizer-219511.patch
--- llvm-toolchain-18-18.1.8/debian/patches/sanitizer-219511.patch	1970-01-01 01:00:00.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/sanitizer-219511.patch	2026-01-31 19:38:31.000000000 +0100
@@ -0,0 +1,23 @@
+From d9d947ffadf1cebcb8cc14a18d7ed970332231ff Mon Sep 17 00:00:00 2001
+From: Tom Tromey <tromey at adacore.com>
+Date: Mon, 31 Aug 2026 08:12:00 -0600
+Subject: [PATCH] Remove two declarations without definitions (#219511)
+
+Commit 3dc4fd6d removed the definitions of struct_scc_modem_sz and
+struct_scc_stat_sz, but left the declarations in a header. This patch
+removes the leftovers.
+---
+ compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+@@ -1042,8 +1042,6 @@
+ extern unsigned struct_kbsentry_sz;
+ extern unsigned struct_mtconfiginfo_sz;
+ extern unsigned struct_nr_parms_struct_sz;
+-extern unsigned struct_scc_modem_sz;
+-extern unsigned struct_scc_stat_sz;
+ extern unsigned struct_serial_multiport_struct_sz;
+ extern unsigned struct_serial_struct_sz;
+ extern unsigned struct_sockaddr_ax25_sz;
diff -Nru llvm-toolchain-18-18.1.8/debian/patches/series llvm-toolchain-18-18.1.8/debian/patches/series
--- llvm-toolchain-18-18.1.8/debian/patches/series	2025-11-08 08:52:54.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/patches/series	2026-01-31 19:38:31.000000000 +0100
@@ -169,3 +169,11 @@
 ubuntu-resolute.patch
 CVE-2024-7883.diff
 powerpc-fix-SIGILL.diff
+sanitizer-194116.patch
+sanitizer-219511.patch
+clang-90517.patch
+clang-197215.patch
+clang-83431.patch
+cmake-210496.patch
+optrecord-131214.patch
+integration-test-suite-cmake.diff
diff -Nru llvm-toolchain-18-18.1.8/debian/qualify-clang.sh llvm-toolchain-18-18.1.8/debian/qualify-clang.sh
--- llvm-toolchain-18-18.1.8/debian/qualify-clang.sh	2025-01-21 09:04:30.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/qualify-clang.sh	2026-01-31 19:38:31.000000000 +0100
@@ -791,7 +791,7 @@
     mkdir -p "${cmake_test_dir}"
 
     cat > "${cmake_test_dir}/CMakeLists.txt" <<EOF
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.5)
 project(test)
 find_package(ZLIB)
 EOF
diff -Nru llvm-toolchain-18-18.1.8/debian/tests/control llvm-toolchain-18-18.1.8/debian/tests/control
--- llvm-toolchain-18-18.1.8/debian/tests/control	2025-02-12 14:25:50.000000000 +0100
+++ llvm-toolchain-18-18.1.8/debian/tests/control	2026-01-31 19:38:31.000000000 +0100
@@ -18,7 +18,7 @@
 Depends: gcc, build-essential, cmake, llvm-18-dev, clang-18, libclang-18-dev
 
 Test-Command: python3 -c "import lldb; print(lldb.__file__); print(lldb)"
-Depends: python3-lldb-18
+Depends: python3-lldb-18, python3
 
 Test-Command: python3 -c "import clang; print(clang.__file__); print(clang)"
-Depends: python3-clang-18
+Depends: python3-clang-18, python3


More information about the Pkg-llvm-team mailing list