================
@@ -170,8 +324,504 @@ RValue WebAssemblyABIInfo::EmitVAArg(CodeGenFunction 
&CGF, Address VAListAddr,
                           /*AllowHigherAlign=*/true, Slot);
 }
 
+// Generate wrapper name for runtime function pointer binding
+std::string WebAssemblyTargetCodeGenInfo::getRuntimeWrapperName(
+    const FunctionProtoType *SrcProto, const FunctionProtoType *DstProto,
+    const ASTContext &Ctx) const {
+  std::string Name = "__wasm_runtime_wrapper_";
+
+  // Encode source signature
+  QualType SrcRetTy = SrcProto->getReturnType();
+  if (SrcRetTy->isVoidType()) {
+    Name += 'v';
+  } else {
+    Name += getTypeSig(SrcRetTy, Ctx);
+  }
+  for (QualType ParamType : SrcProto->param_types()) {
+    Name += getTypeSig(ParamType, Ctx);
+  }
+
+  Name += "_to_";
+
+  // Encode destination signature
+  QualType DstRetTy = DstProto->getReturnType();
+  if (DstRetTy->isVoidType()) {
+    Name += 'v';
+  } else {
+    Name += getTypeSig(DstRetTy, Ctx);
+  }
+  for (QualType ParamType : DstProto->param_types()) {
+    Name += getTypeSig(ParamType, Ctx);
+  }
+
+  return Name;
+}
+
+// Emit runtime binding for function pointer cast
+// This handles cases like g_list_free_full where a runtime parameter
+// needs to be cast from fewer params to more params
+llvm::Value 
*WebAssemblyTargetCodeGenInfo::emitWasmRuntimeFunctionPointerBinding(
+    CodeGenFunction &CGF, llvm::Value *FnPtr, QualType SrcType,
+    QualType DstType, bool IsImmediate) const {
+
+  const FunctionProtoType *SrcProto =
+      SrcType->getPointeeType()->getAs<FunctionProtoType>();
+  const FunctionProtoType *DstProto =
+      DstType->getPointeeType()->getAs<FunctionProtoType>();
+
+  if (!SrcProto || !DstProto)
+    return nullptr;
+
+  // Check parameter counts: source must have same or fewer params than 
destination
+  // We can add parameters (caller provides them, we ignore extras when 
calling source)
+  // We cannot remove parameters (caller doesn't provide them, we can't invent 
values)
+  unsigned SrcParams = SrcProto->getNumParams();
+  unsigned DstParams = DstProto->getNumParams();
+
+  if (SrcParams > DstParams)
+    return nullptr;  // Can't remove parameters
+
+  // Check return types: we can discard a return value but cannot invent one.
+  // Compare LLVM types (not C types) since wasm only cares about 
i32/i64/f32/f64.
+  QualType SrcRetTy = SrcProto->getReturnType();
+  QualType DstRetTy = DstProto->getReturnType();
+  llvm::Type *SrcRetLLVMTy = CGF.CGM.getTypes().ConvertType(SrcRetTy);
+  llvm::Type *DstRetLLVMTy = CGF.CGM.getTypes().ConvertType(DstRetTy);
+  bool sameReturnType = SrcRetLLVMTy == DstRetLLVMTy;
+
+  if (!DstRetTy->isVoidType() && !sameReturnType)
+    return nullptr;  // Can't invent return values
+
+  // Reject if signatures are identical (no adaptation needed)
+  if (SrcParams == DstParams && sameReturnType)
+    return nullptr;
+
+  // A null function pointer needs no wrapper — fall through to bitcast
+  if (isa<llvm::ConstantPointerNull>(FnPtr))
+    return nullptr;
+
+  LLVM_DEBUG(llvm::dbgs() << "emitWasmRuntimeFunctionPointerBinding: "
+                          << "src params=" << SrcParams
+                          << " dst params=" << DstParams << "\n");
+
+  llvm::Module &M = CGF.CGM.getModule();
+  llvm::LLVMContext &Context = M.getContext();
+  llvm::PointerType *PtrTy = llvm::PointerType::getUnqual(Context);
+  llvm::Type *I32Ty = llvm::IntegerType::getInt32Ty(Context);
+
+  // Pre-allocated pool: N wrapper functions + N TLS slots per signature pair.
+  // Each runtime invocation atomically claims a slot. This supports both
+  // "call immediately" and "store for later" patterns without overwrites.
+  static const unsigned POOL_SIZE = 64;
+
+  std::string WrapperName = getRuntimeWrapperName(SrcProto, DstProto, 
CGF.CGM.getContext());
+
+  std::string SourceId = M.getSourceFileName();
+  if (SourceId.empty())
+    SourceId = M.getName();
+  for (char &C : SourceId)
+    if (!isalnum(C) && C != '_')
+      C = '_';
+  WrapperName += "_" + SourceId;
+
+  std::string PoolName = "__wasm_runtime_pool_" + WrapperName;
+
+  // Get or create pool globals (once per module per signature pair)
+  llvm::GlobalVariable *Counter = M.getNamedGlobal(PoolName + "_counter");
+  llvm::GlobalVariable *ImmediateSlot = M.getNamedGlobal(PoolName + 
"_immediate_slot");
+  llvm::Function *ImmediateWrapper = M.getFunction(WrapperName + "_immediate");
+  llvm::ArrayType *SlotArrayTy = llvm::ArrayType::get(PtrTy, POOL_SIZE);
+  llvm::GlobalVariable *Slots = nullptr;
+  llvm::GlobalVariable *WrapperTable = nullptr;
+  llvm::FunctionType *SrcFnType = nullptr;
+  llvm::FunctionType *DstFnType = nullptr;
+
+  if (!Counter) {
+    SrcFnType = llvm::cast<llvm::FunctionType>(
+        CGF.CGM.getTypes().ConvertType(QualType(SrcProto, 0)));
+    DstFnType = llvm::cast<llvm::FunctionType>(
+        CGF.CGM.getTypes().ConvertType(QualType(DstProto, 0)));
+
+    Counter = new llvm::GlobalVariable(
+        M, I32Ty, false, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantInt::get(I32Ty, 0), PoolName + "_counter");
+    Counter->setThreadLocalMode(llvm::GlobalValue::GeneralDynamicTLSModel);
+
+    // Immediate-call TLS slot: per-thread, no races, reused every call
+    ImmediateSlot = new llvm::GlobalVariable(
+        M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantPointerNull::get(PtrTy), PoolName + "_immediate_slot");
+    
ImmediateSlot->setThreadLocalMode(llvm::GlobalValue::GeneralDynamicTLSModel);
+
+    // Immediate wrapper: loads from TLS slot, calls with adapted signature
+    ImmediateWrapper = llvm::Function::Create(
+        DstFnType, llvm::GlobalValue::InternalLinkage,
+        WrapperName + "_immediate", M);
+    ImmediateWrapper->addFnAttr(llvm::Attribute::NoInline);
+    ImmediateWrapper->addFnAttr(llvm::Attribute::NoUnwind);
+    {
+      llvm::BasicBlock *BB = llvm::BasicBlock::Create(Context, "entry", 
ImmediateWrapper);
+      llvm::IRBuilder<> B(BB);
+      llvm::Value *FP = B.CreateLoad(PtrTy, ImmediateSlot);
+      llvm::BasicBlock *CallBB = llvm::BasicBlock::Create(Context, "call", 
ImmediateWrapper);
+      llvm::BasicBlock *NullBB = llvm::BasicBlock::Create(Context, "nullslot", 
ImmediateWrapper);
+      B.CreateCondBr(B.CreateIsNotNull(FP), CallBB, NullBB);
+      B.SetInsertPoint(CallBB);
+      llvm::SmallVector<llvm::Value *, 8> ImmArgs;
+      auto AI = ImmediateWrapper->arg_begin();
+      for (unsigned J = 0; J < SrcParams && AI != ImmediateWrapper->arg_end(); 
++J, ++AI) {
+        llvm::Value *A = &*AI;
+        if (A->getType() != SrcFnType->getParamType(J))
+          A = B.CreateBitOrPointerCast(A, SrcFnType->getParamType(J));
+        ImmArgs.push_back(A);
+      }
+      llvm::CallInst *ImmCall = B.CreateCall(SrcFnType, FP, ImmArgs);
+      if (DstFnType->getReturnType()->isVoidTy()) {
+        B.CreateRetVoid(); B.SetInsertPoint(NullBB); B.CreateRetVoid();
+      } else {
+        llvm::Value *R = ImmCall;
+        if (R->getType() != DstFnType->getReturnType())
+          R = B.CreateBitOrPointerCast(R, DstFnType->getReturnType());
+        B.CreateRet(R);
+        B.SetInsertPoint(NullBB);
+        B.CreateRet(llvm::Constant::getNullValue(DstFnType->getReturnType()));
+      }
+    }
+
+    Slots = new llvm::GlobalVariable(
+        M, SlotArrayTy, false, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantAggregateZero::get(SlotArrayTy), PoolName + "_slots");
+
+    // 8-entry direct-mapped cache: avoids pool allocation for repeated fn_ptrs
+    static const unsigned CACHE_SIZE = 8;
+    llvm::ArrayType *CacheTy = llvm::ArrayType::get(PtrTy, CACHE_SIZE);
+    new llvm::GlobalVariable(
+        M, CacheTy, false, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantAggregateZero::get(CacheTy), PoolName + "_cache_keys");
+    new llvm::GlobalVariable(
+        M, CacheTy, false, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantAggregateZero::get(CacheTy), PoolName + 
"_cache_wrappers");
+
+    // Pre-generate POOL_SIZE wrapper functions + build lookup table
+    llvm::SmallVector<llvm::Constant *, 64> WrappersConst;
+    for (unsigned I = 0; I < POOL_SIZE; ++I) {
+      std::string InstName = WrapperName + "_" + std::to_string(I);
+      llvm::Function *W = llvm::Function::Create(
+          DstFnType, llvm::GlobalValue::InternalLinkage, InstName, M);
+      W->addFnAttr(llvm::Attribute::NoInline);
+      W->addFnAttr(llvm::Attribute::NoUnwind);
+
+      llvm::BasicBlock *BB = llvm::BasicBlock::Create(Context, "entry", W);
+      llvm::IRBuilder<> B(BB);
+
+      llvm::Value *SlotPtr = B.CreateConstInBoundsGEP1_32(PtrTy, Slots, I);
+      llvm::Value *FP = B.CreateLoad(PtrTy, SlotPtr);
+
+      // Defensive null check: if slot was never written, skip call
+      llvm::BasicBlock *CallBB = llvm::BasicBlock::Create(Context, "call", W);
+      llvm::BasicBlock *NullBB = llvm::BasicBlock::Create(Context, "nullslot", 
W);
+      llvm::Value *IsNotNull = B.CreateIsNotNull(FP);
+      B.CreateCondBr(IsNotNull, CallBB, NullBB);
+
+      B.SetInsertPoint(CallBB);
+      llvm::SmallVector<llvm::Value *, 8> CallArgs;
+      auto ArgIt = W->arg_begin();
+      for (unsigned J = 0; J < SrcParams && ArgIt != W->arg_end(); ++J, 
++ArgIt) {
+        llvm::Value *A = &*ArgIt;
+        if (A->getType() != SrcFnType->getParamType(J))
+          A = B.CreateBitOrPointerCast(A, SrcFnType->getParamType(J));
+        CallArgs.push_back(A);
+      }
+      llvm::CallInst *Call = B.CreateCall(SrcFnType, FP, CallArgs);
+
+      if (DstFnType->getReturnType()->isVoidTy()) {
+        B.CreateRetVoid();
+        B.SetInsertPoint(NullBB);
+        B.CreateRetVoid();
+      } else {
+        llvm::Value *Ret = Call;
+        if (Ret->getType() != DstFnType->getReturnType())
+          Ret = B.CreateBitOrPointerCast(Ret, DstFnType->getReturnType());
+        B.CreateRet(Ret);
+        B.SetInsertPoint(NullBB);
+        B.CreateRet(llvm::Constant::getNullValue(DstFnType->getReturnType()));
+      }
+
+      WrappersConst.push_back(llvm::ConstantExpr::getBitCast(W, PtrTy));
+    }
+
+    // Create constant lookup table (not TLS — read-only function pointers)
+    llvm::ArrayType *WrapTblTy = llvm::ArrayType::get(PtrTy, POOL_SIZE);
+    WrapperTable = new llvm::GlobalVariable(
+        M, WrapTblTy, true, llvm::GlobalValue::InternalLinkage,
+        llvm::ConstantArray::get(WrapTblTy, WrappersConst),
+        PoolName + "_wrappers");
+    WrapperTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+  } else {
+    Slots = M.getNamedGlobal(PoolName + "_slots");
+    WrapperTable = M.getNamedGlobal(PoolName + "_wrappers");
+    SrcFnType = llvm::cast<llvm::FunctionType>(
+        CGF.CGM.getTypes().ConvertType(QualType(SrcProto, 0)));
+  }
+
+  // Runtime null check
+  llvm::Value *IsNull = CGF.Builder.CreateIsNull(FnPtr);
+  llvm::BasicBlock *NullContBB = llvm::BasicBlock::Create(Context, "nullcont", 
CGF.CurFn);
+  llvm::BasicBlock *NotNullBB = llvm::BasicBlock::Create(Context, "notnull", 
CGF.CurFn);
+  CharUnits PtrAlign = CGF.CGM.getPointerAlign();
+
+  if (IsImmediate) {
+    // === Immediate call: 1 TLS slot + 1 wrapper, no branches after null 
check ===
+    CGF.Builder.CreateCondBr(IsNull, NullContBB, NotNullBB);
+
+    CGF.Builder.SetInsertPoint(NotNullBB);
+    CGF.Builder.CreateStore(FnPtr, Address(ImmediateSlot, PtrTy, PtrAlign));
+    CGF.Builder.CreateBr(NullContBB);
+
+    CGF.Builder.SetInsertPoint(NullContBB);
+    llvm::PHINode *PHI = CGF.Builder.CreatePHI(PtrTy, 2);
+    PHI->addIncoming(llvm::ConstantExpr::getBitCast(ImmediateWrapper, PtrTy), 
NotNullBB);
+    PHI->addIncoming(llvm::ConstantPointerNull::get(PtrTy), NullContBB);
+    return PHI;
+  }
+
+  // === Store-for-later: pool with 64 slots + 8-entry cache + atomic counter 
===
+  CGF.Builder.CreateCondBr(IsNull, NullContBB, NotNullBB);
+
+  CGF.Builder.SetInsertPoint(NotNullBB);
+  llvm::ArrayType *WrapTblTy = llvm::ArrayType::get(PtrTy, POOL_SIZE);
+  static const unsigned CACHE_SIZE = 8;
+  llvm::ArrayType *CacheTy = llvm::ArrayType::get(PtrTy, CACHE_SIZE);
+  llvm::GlobalVariable *CacheKeys = M.getNamedGlobal(PoolName + "_cache_keys");
+  llvm::GlobalVariable *CacheWrappers = M.getNamedGlobal(PoolName + 
"_cache_wrappers");
+  llvm::BasicBlock *CacheHitBB = llvm::BasicBlock::Create(Context, "cachehit", 
CGF.CurFn);
+  llvm::BasicBlock *CacheMissBB = llvm::BasicBlock::Create(Context, 
"cachemiss", CGF.CurFn);
+  llvm::BasicBlock *ScanBB = llvm::BasicBlock::Create(Context, "scan", 
CGF.CurFn);
+  llvm::BasicBlock *ScanFoundBB = llvm::BasicBlock::Create(Context, "scanfnd", 
CGF.CurFn);
+  llvm::BasicBlock *ScanNextBB = llvm::BasicBlock::Create(Context, "scannxt", 
CGF.CurFn);
+  llvm::BasicBlock *AllocCheckBB = llvm::BasicBlock::Create(Context, 
"allocchk", CGF.CurFn);
+  llvm::BasicBlock *AllocStoreBB = llvm::BasicBlock::Create(Context, 
"allocstr", CGF.CurFn);
+  llvm::BasicBlock *OverflowBB = llvm::BasicBlock::Create(Context, "overflow", 
CGF.CurFn);
+  llvm::BasicBlock *ContBB = llvm::BasicBlock::Create(Context, "cont", 
CGF.CurFn);
+
+  // Cache lookup: idx = (fn_ptr >> 2) & 7
+  llvm::Value *CacheIdx = CGF.Builder.CreateAnd(
+      CGF.Builder.CreateLShr(
+          CGF.Builder.CreatePtrToInt(FnPtr, I32Ty),
+          llvm::ConstantInt::get(I32Ty, 2)),
+      llvm::ConstantInt::get(I32Ty, CACHE_SIZE - 1));
+  llvm::Value *CacheKeyGEP = CGF.Builder.CreateInBoundsGEP(
+      CacheTy, CacheKeys, {llvm::ConstantInt::get(I32Ty, 0), CacheIdx});
+  Address CacheKeyAddr(CacheKeyGEP, PtrTy, PtrAlign);
+  llvm::Value *CachedFn = CGF.Builder.CreateLoad(CacheKeyAddr);
+  llvm::Value *CacheHit = CGF.Builder.CreateICmpEQ(CachedFn, FnPtr);
+  llvm::Value *CacheWrapGEP = CGF.Builder.CreateInBoundsGEP(
+      CacheTy, CacheWrappers, {llvm::ConstantInt::get(I32Ty, 0), CacheIdx});
+  Address CacheWrapAddr(CacheWrapGEP, PtrTy, PtrAlign);
+
+  CGF.Builder.CreateCondBr(CacheHit, CacheHitBB, CacheMissBB);
+
+  // Cache hit: load cached wrapper, branch to cont
+  CGF.Builder.SetInsertPoint(CacheHitBB);
+  llvm::Value *CacheHitW = CGF.Builder.CreateLoad(CacheWrapAddr);
+  CGF.Builder.CreateBr(ContBB);
+
+  // Cache miss: scan pool for existing mapping
+  CGF.Builder.SetInsertPoint(CacheMissBB);
+  CGF.Builder.CreateBr(ScanBB);
+
+  // Scan loop: find fn_ptr in slots[0..POOL_SIZE-1]
+  CGF.Builder.SetInsertPoint(ScanBB);
+  llvm::PHINode *ScanIdx = CGF.Builder.CreatePHI(I32Ty, 2);
+  ScanIdx->addIncoming(llvm::ConstantInt::get(I32Ty, 0), CacheMissBB);
+  llvm::Value *ScanSlotGEP = CGF.Builder.CreateInBoundsGEP(
+      SlotArrayTy, Slots, {llvm::ConstantInt::get(I32Ty, 0), ScanIdx});
+  llvm::Value *ScanFn = CGF.Builder.CreateLoad(Address(ScanSlotGEP, PtrTy, 
PtrAlign));
+  llvm::Value *ScanMatch = CGF.Builder.CreateICmpEQ(ScanFn, FnPtr);
+  CGF.Builder.CreateCondBr(ScanMatch, ScanFoundBB, ScanNextBB);
+
+  // Found existing slot: update cache, return existing wrapper
+  CGF.Builder.SetInsertPoint(ScanFoundBB);
+  CGF.Builder.CreateStore(FnPtr, CacheKeyAddr);
+  llvm::Value *FoundWrapGEP = CGF.Builder.CreateInBoundsGEP(
+      WrapTblTy, WrapperTable, {llvm::ConstantInt::get(I32Ty, 0), ScanIdx});
+  llvm::Value *FoundW = CGF.Builder.CreateLoad(Address(FoundWrapGEP, PtrTy, 
PtrAlign));
+  CGF.Builder.CreateStore(FoundW, CacheWrapAddr);
+  CGF.Builder.CreateBr(ContBB);
+
+  // Advance scan
+  CGF.Builder.SetInsertPoint(ScanNextBB);
+  llvm::Value *NextIdx = CGF.Builder.CreateAdd(
+      ScanIdx, llvm::ConstantInt::get(I32Ty, 1));
+  llvm::Value *ScanEnd = CGF.Builder.CreateICmpUGE(
+      NextIdx, llvm::ConstantInt::get(I32Ty, POOL_SIZE));
+  ScanIdx->addIncoming(NextIdx, ScanNextBB);
+  CGF.Builder.CreateCondBr(ScanEnd, AllocCheckBB, ScanBB);
+
+  // Allocate new slot: atomic counter increment
+  CGF.Builder.SetInsertPoint(AllocCheckBB);
+  Address CounterAddr(Counter, I32Ty, PtrAlign);
+  llvm::Value *Slot = CGF.Builder.CreateAtomicRMW(
+      llvm::AtomicRMWInst::Add, CounterAddr,
+      llvm::ConstantInt::get(I32Ty, 1), llvm::AtomicOrdering::Monotonic);
+  llvm::Value *InBounds = CGF.Builder.CreateICmpULT(
+      Slot, llvm::ConstantInt::get(I32Ty, POOL_SIZE));
+  CGF.Builder.CreateCondBr(InBounds, AllocStoreBB, OverflowBB);
+
+  // Overflow
+  CGF.Builder.SetInsertPoint(OverflowBB);
+  CGF.Builder.CreateCall(llvm::Intrinsic::getOrInsertDeclaration(
+      &M, llvm::Intrinsic::trap));
+  CGF.Builder.CreateUnreachable();
+
+  // Store in pool + update cache
+  CGF.Builder.SetInsertPoint(AllocStoreBB);
+  llvm::Value *SlotIdx[] = {llvm::ConstantInt::get(I32Ty, 0), Slot};
+  llvm::Value *SlotGEP = CGF.Builder.CreateInBoundsGEP(
+      SlotArrayTy, Slots, SlotIdx);
+  CGF.Builder.CreateStore(FnPtr, Address(SlotGEP, PtrTy, PtrAlign));
+  llvm::Value *WrapGEP = CGF.Builder.CreateInBoundsGEP(
+      WrapTblTy, WrapperTable, SlotIdx);
+  llvm::Value *W = CGF.Builder.CreateLoad(Address(WrapGEP, PtrTy, PtrAlign));
+  CGF.Builder.CreateStore(FnPtr, CacheKeyAddr);
+  CGF.Builder.CreateStore(W, CacheWrapAddr);
+  CGF.Builder.CreateBr(ContBB);
+
+  // Null path
+  CGF.Builder.SetInsertPoint(NullContBB);
+  CGF.Builder.CreateBr(ContBB);
+
+  // ContBB: PHI for result
+  CGF.Builder.SetInsertPoint(ContBB);
+  llvm::PHINode *PHI = CGF.Builder.CreatePHI(PtrTy, 4);
+  PHI->addIncoming(CacheHitW, CacheHitBB);
+  PHI->addIncoming(FoundW, ScanFoundBB);
+  PHI->addIncoming(W, AllocStoreBB);
+  PHI->addIncoming(llvm::ConstantPointerNull::get(PtrTy), NullContBB);
+  return PHI;
+}
+
 std::unique_ptr<TargetCodeGenInfo>
 CodeGen::createWebAssemblyTargetCodeGenInfo(CodeGenModule &CGM,
                                             WebAssemblyABIKind K) {
   return std::make_unique<WebAssemblyTargetCodeGenInfo>(CGM.getTypes(), K);
 }
+
+// Helper to get the type signature character for a given QualType
+// Returns a character that represents the given QualType in a wasm signature.
+// See getInvokeSig() in WebAssemblyAsmPrinter for related logic.
+char WebAssemblyTargetCodeGenInfo::getTypeSig(const QualType &Ty,
+                                              const ASTContext &Ctx) const {
+  if (Ty->isAnyPointerType()) {
----------------
turran wrote:

Hello @kleisauke 
Thanks for the feedback. Given the current status of the PR, I can build GLib 
without your fix function pointer patch and only apply a small one. The whole 
GStreamer works without any function signature mismatch, both static and 
runtime casts. Let me know if something is still missing. I've also added a 
documentation file that explains the cases where it is impossible for the 
compiler to fix, the GLib patch only addresses such situations.

<details>

<summary>The patch</summary>
```
diff --git a/glib/glist.c b/glib/glist.c
index 754a3ec52..1e13b4087 100644
--- a/glib/glist.c
+++ b/glib/glist.c
@@ -1097,7 +1097,7 @@ g_list_foreach (GList    *list,
 static GList*
 g_list_insert_sorted_real (GList    *list,
                            gpointer  data,
-                           GFunc     func,
+                           GCompareDataFunc     func,
                            gpointer  user_data)
 {
   GList *tmp_list = list;
@@ -1113,13 +1113,13 @@ g_list_insert_sorted_real (GList    *list,
       return new_list;
     }
   
-  cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+  cmp = func (data, tmp_list->data, user_data);
 
   while ((tmp_list->next) && (cmp > 0))
     {
       tmp_list = tmp_list->next;
 
-      cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+      cmp = func (data, tmp_list->data, user_data);
     }
 
   new_list = _g_list_alloc0 ();
@@ -1170,7 +1170,7 @@ g_list_insert_sorted (GList        *list,
                       gpointer      data,
                       GCompareFunc  func)
 {
-  return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
+  return g_list_insert_sorted_real (list, data, (GCompareDataFunc) func, NULL);
 }
 
 /**
@@ -1201,13 +1201,13 @@ g_list_insert_sorted_with_data (GList            *list,
                                 GCompareDataFunc  func,
                                 gpointer          user_data)
 {
-  return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
+  return g_list_insert_sorted_real (list, data, func, user_data);
 }
 
 static GList *
 g_list_sort_merge (GList     *l1, 
                    GList     *l2,
-                   GFunc     compare_func,
+                   GCompareDataFunc     compare_func,
                    gpointer  user_data)
 {
   GList list, *l, *lprev;
@@ -1218,7 +1218,7 @@ g_list_sort_merge (GList     *l1,
 
   while (l1 && l2)
     {
-      cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
+      cmp = compare_func (l1->data, l2->data, user_data);
 
       if (cmp <= 0)
         {
@@ -1242,7 +1242,7 @@ g_list_sort_merge (GList     *l1,
 
 static GList * 
 g_list_sort_real (GList    *list,
-                  GFunc     compare_func,
+                  GCompareDataFunc     compare_func,
                   gpointer  user_data)
 {
   GList *l1, *l2;
@@ -1301,7 +1301,7 @@ GList *
 g_list_sort (GList        *list,
              GCompareFunc  compare_func)
 {
-  return g_list_sort_real (list, (GFunc) compare_func, NULL);
+  return g_list_sort_real (list, (GCompareDataFunc) compare_func, NULL);
 }
 
 /**
@@ -1334,7 +1334,7 @@ g_list_sort_with_data (GList            *list,
                        GCompareDataFunc  compare_func,
                        gpointer          user_data)
 {
-  return g_list_sort_real (list, (GFunc) compare_func, user_data);
+  return g_list_sort_real (list, compare_func, user_data);
 }
 
 /**
diff --git a/glib/gslist.c b/glib/gslist.c
index 7d4051c24..120a35363 100644
--- a/glib/gslist.c
+++ b/glib/gslist.c
@@ -890,10 +890,10 @@ g_slist_foreach (GSList   *list,
 }
 
 static GSList*
-g_slist_insert_sorted_real (GSList   *list,
-                            gpointer  data,
-                            GFunc     func,
-                            gpointer  user_data)
+g_slist_insert_sorted_real (GSList               *list,
+                            gpointer             data,
+                            GCompareDataFunc     func,
+                            gpointer             user_data)
 {
   GSList *tmp_list = list;
   GSList *prev_list = NULL;
@@ -910,14 +910,14 @@ g_slist_insert_sorted_real (GSList   *list,
       return new_list;
     }
 
-  cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+  cmp = func (data, tmp_list->data, user_data);
 
   while ((tmp_list->next) && (cmp > 0))
     {
       prev_list = tmp_list;
       tmp_list = tmp_list->next;
 
-      cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+      cmp = func (data, tmp_list->data, user_data);
     }
 
   new_list = _g_slist_alloc ();
@@ -961,7 +961,7 @@ g_slist_insert_sorted (GSList       *list,
                        gpointer      data,
                        GCompareFunc  func)
 {
-  return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL);
+  return g_slist_insert_sorted_real (list, data, (GCompareDataFunc) func, 
NULL);
 }
 
 /**
@@ -986,14 +986,14 @@ g_slist_insert_sorted_with_data (GSList           *list,
                                  GCompareDataFunc  func,
                                  gpointer          user_data)
 {
-  return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data);
+  return g_slist_insert_sorted_real (list, data, func, user_data);
 }
 
 static GSList *
-g_slist_sort_merge (GSList   *l1,
-                    GSList   *l2,
-                    GFunc     compare_func,
-                    gpointer  user_data)
+g_slist_sort_merge (GSList               *l1,
+                    GSList               *l2,
+                    GCompareDataFunc     compare_func,
+                    gpointer             user_data)
 {
   GSList list, *l;
   gint cmp;
@@ -1002,7 +1002,7 @@ g_slist_sort_merge (GSList   *l1,
 
   while (l1 && l2)
     {
-      cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
+      cmp = compare_func (l1->data, l2->data, user_data);
 
       if (cmp <= 0)
         {
@@ -1021,9 +1021,9 @@ g_slist_sort_merge (GSList   *l1,
 }
 
 static GSList *
-g_slist_sort_real (GSList   *list,
-                   GFunc     compare_func,
-                   gpointer  user_data)
+g_slist_sort_real (GSList               *list,
+                   GCompareDataFunc     compare_func,
+                   gpointer             user_data)
 {
   GSList *l1, *l2;
 
@@ -1068,7 +1068,7 @@ GSList *
 g_slist_sort (GSList       *list,
               GCompareFunc  compare_func)
 {
-  return g_slist_sort_real (list, (GFunc) compare_func, NULL);
+  return g_slist_sort_real (list, (GCompareDataFunc) compare_func, NULL);
 }
 
 /**
@@ -1086,7 +1086,7 @@ g_slist_sort_with_data (GSList           *list,
                         GCompareDataFunc  compare_func,
                         gpointer          user_data)
 {
-  return g_slist_sort_real (list, (GFunc) compare_func, user_data);
+  return g_slist_sort_real (list, compare_func, user_data);
 }
 
 /**
```
</details>

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

Reply via email to