================
@@ -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()) {
----------------
kleisauke wrote:

It looks like `isAnyPointerType()` doesn't catch C++ pointer types, so perhaps 
this should be:
```suggestion
  if (Ty->isCompoundType()) {
```

While this isn't reproducible with the current changes in this PR, it came up 
during the effort to sync `getOrCreateWasmFunctionPointerThunk()` with the 
`WebAssemblyFixFunctionBitcasts` pass.

<details>
  <summary>Details</summary>

Tested with these changesets:
https://github.com/fluendo/llvm-project/compare/218e499fe206f02894954bbd5aa5ddb3e5e78a48...kleisauke:wasm-function-pointers-rebase6
https://github.com/kleisauke/wasm-vips/compare/1740576a2cdcdd3a31ed6c4a370cd4e357554819...llvm-pr-153168

```console
FAILED: [code=262] gobject/libgobject-2.0.a.p/gsourceclosure.c.o 
emcc -Igobject/libgobject-2.0.a.p -Igobject -I../gobject -I. -I.. -Iglib 
-I../glib -fvisibility=hidden -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 
-Wall -Winvalid-pch -Wextra -Wpedantic -std=gnu99 -O3 -D_GNU_SOURCE 
-fno-strict-aliasing -DG_DISABLE_CAST_CHECKS -DG_DISABLE_ASSERT 
-DG_DISABLE_CHECKS -Wfloat-conversion -Wimplicit-fallthrough 
-Wmisleading-indentation -Wmissing-field-initializers -Wnonnull 
-Wnull-dereference -Wunused -Wno-unused-parameter -Wno-cast-function-type 
-Wno-pedantic -Wno-format-zero-length -Wno-variadic-macros -Werror=format=2 
-Werror=init-self -Werror=missing-include-dirs -Werror=pointer-arith 
-Werror=unused-result -Wstrict-prototypes -Wno-bad-function-cast 
-Werror=implicit-function-declaration -Werror=missing-prototypes 
-Werror=pointer-sign -Wno-string-plus-int -Wno-typedef-redefinition -Os 
-pthread -fwasm-exceptions -fvisibility=hidden -fwasm-fix-function-bitcasts 
-msimd128 -DWASM_SIMD_COMPAT_SLOW -fPIC '-DG_LOG_DOMAIN="GLib-GObject"' 
-DGOBJECT_COMPILATION -Wsign-conversion -Wshorten-64-to-32 -MD -MQ 
gobject/libgobject-2.0.a.p/gsourceclosure.c.o -MF 
gobject/libgobject-2.0.a.p/gsourceclosure.c.o.d -o 
gobject/libgobject-2.0.a.p/gsourceclosure.c.o -c ../gobject/gsourceclosure.c
../gobject/gsourceclosure.c:82:1: warning: unused function 
'io_watch_closure_callback' [-Wunused-function]
   82 | io_watch_closure_callback (GIOChannel   *channel,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~
Unhandled QualType
UNREACHABLE executed at 
/home/kleisauke/emsdk/llvm/git/src/clang/lib/CodeGen/Targets/WebAssembly.cpp:707!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and 
include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: 
/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang
 -target wasm32-unknown-emscripten -mllvm -combiner-global-alias-analysis=false 
-mllvm -wasm-enable-sjlj -mllvm -wasm-use-legacy-eh -mllvm -disable-lsr 
--sysroot=/home/kleisauke/emsdk/emscripten/main/cache/sysroot 
-D__EMSCRIPTEN_SHARED_MEMORY__=1 -Xclang -iwithsysroot/include/fakesdl -Xclang 
-iwithsysroot/include/compat -Igobject/libgobject-2.0.a.p -Igobject 
-I../gobject -I. -I.. -Iglib -I../glib -fvisibility=hidden 
-fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra 
-Wpedantic -std=gnu99 -O3 -D_GNU_SOURCE -fno-strict-aliasing 
-DG_DISABLE_CAST_CHECKS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS 
-Wfloat-conversion -Wimplicit-fallthrough -Wmisleading-indentation 
-Wmissing-field-initializers -Wnonnull -Wnull-dereference -Wunused 
-Wno-unused-parameter -Wno-cast-function-type -Wno-pedantic 
-Wno-format-zero-length -Wno-variadic-macros -Werror=format=2 -Werror=init-self 
-Werror=missing-include-dirs -Werror=pointer-arith -Werror=unused-result 
-Wstrict-prototypes -Wno-bad-function-cast 
-Werror=implicit-function-declaration -Werror=missing-prototypes 
-Werror=pointer-sign -Wno-string-plus-int -Wno-typedef-redefinition -Os 
-pthread -fwasm-exceptions -fvisibility=hidden -fwasm-fix-function-bitcasts 
-msimd128 -DWASM_SIMD_COMPAT_SLOW -fPIC -DG_LOG_DOMAIN=\"GLib-GObject\" 
-DGOBJECT_COMPILATION -Wsign-conversion -Wshorten-64-to-32 -MD -MQ 
gobject/libgobject-2.0.a.p/gsourceclosure.c.o -MF 
gobject/libgobject-2.0.a.p/gsourceclosure.c.o.d 
-ogobject/libgobject-2.0.a.p/gsourceclosure.c.o -c ../gobject/gsourceclosure.c
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      ../gobject/gsourceclosure.c:32:1 <Spelling=<scratch space>:46:1>: 
Generating code for declaration 'g_io_channel_get_type_once'
 #0 0x00000000024ea2e1 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x24ea2e1)
 #1 0x00000000024e7ba7 llvm::sys::CleanupOnSignal(unsigned long) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x24e7ba7)
 #2 0x0000000002418144 CrashRecoverySignalHandler(int) 
CrashRecoveryContext.cpp:0:0
 #3 0x00007efe29d0a0b0 __restore_rt (/lib64/libc.so.6+0x1a0b0)
 #4 0x00007efe29d64dcc __pthread_kill_implementation (/lib64/libc.so.6+0x74dcc)
 #5 0x00007efe29d09f8e gsignal (/lib64/libc.so.6+0x19f8e)
 #6 0x00007efe29cf17b3 abort (/lib64/libc.so.6+0x17b3)
 #7 0x0000000002423dbc llvm::llvm_unreachable_internal(char const*, char 
const*, unsigned int) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2423dbc)
 #8 0x0000000002c8fc5d 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2c8fc5d)
 #9 0x0000000002c92271 
WebAssemblyTargetCodeGenInfo::getThunkName(std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char>>, clang::FunctionProtoType const*, 
clang::ASTContext const&) const 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2c92271)
#10 0x0000000002c927d5 
WebAssemblyTargetCodeGenInfo::getOrCreateWasmFunctionPointerThunk(clang::CodeGen::CodeGenModule&,
 llvm::Value*, clang::QualType, clang::QualType) const 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2c927d5)
#11 0x000000000289fe2a (anonymous 
namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) 
CGExprScalar.cpp:0:0
#12 0x000000000289c59f 
clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x289c59f)
#13 0x0000000002d815a4 
clang::CodeGen::CodeGenFunction::EmitScalarInit(clang::Expr const*, 
clang::ValueDecl const*, clang::CodeGen::LValue, bool) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2d815a4)
#14 0x0000000002d82f70 
clang::CodeGen::CodeGenFunction::EmitExprAsInit(clang::Expr const*, 
clang::ValueDecl const*, clang::CodeGen::LValue, bool) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2d82f70)
#15 0x0000000002d8c3c1 
clang::CodeGen::CodeGenFunction::EmitAutoVarInit(clang::CodeGen::CodeGenFunction::AutoVarEmission
 const&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2d8c3c1)
#16 0x0000000002d91079 
clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) (.part.0) 
CGDecl.cpp:0:0
#17 0x0000000002d9180d clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl 
const&, bool) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2d9180d)
#18 0x00000000029b24d4 
clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x29b24d4)
#19 0x00000000029c73c5 
clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, 
llvm::ArrayRef<clang::Attr const*>) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x29c73c5)
#20 0x00000000029be961 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt 
const*, llvm::ArrayRef<clang::Attr const*>) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x29be961)
#21 0x00000000029c6ec3 
clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt
 const&, bool, clang::CodeGen::AggValueSlot) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x29c6ec3)
#22 0x0000000002a2f09c 
clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2a2f09c)
#23 0x0000000002a46054 
clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, 
llvm::Function*, clang::CodeGen::CGFunctionInfo const&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2a46054)
#24 0x0000000002aa8270 
clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, 
llvm::GlobalValue*) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2aa8270)
#25 0x0000000002aa3b94 
clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, 
llvm::GlobalValue*) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2aa3b94)
#26 0x0000000002aaf19e clang::CodeGen::CodeGenModule::EmitDeferred() 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2aaf19e)
#27 0x0000000002ab134e clang::CodeGen::CodeGenModule::Release() 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2ab134e)
#28 0x0000000002e46dac (anonymous 
namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) 
ModuleBuilder.cpp:0:0
#29 0x0000000002e43ff5 
clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2e43ff5)
#30 0x0000000004cb5df4 clang::ParseAST(clang::Sema&, bool, bool) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x4cb5df4)
#31 0x00000000031d94de clang::FrontendAction::Execute() 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x31d94de)
#32 0x000000000314f03b 
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x314f03b)
#33 0x00000000032e8c92 
clang::ExecuteCompilerInvocation(clang::CompilerInstance*) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x32e8c92)
#34 0x0000000000d3d8af cc1_main(llvm::ArrayRef<char const*>, char const*, 
void*) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0xd3d8af)
#35 0x0000000000d35998 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, 
llvm::ToolContext const&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) 
driver.cpp:0:0
#36 0x0000000000d35b7a int llvm::function_ref<int (llvm::SmallVectorImpl<char 
const*>&)>::callback_fn<clang_main(int, char**, llvm::ToolContext 
const&)::'lambda'(llvm::SmallVectorImpl<char const*>&)>(long, 
llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#37 0x0000000002eb8d39 void llvm::function_ref<void 
()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>,
 std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#38 0x000000000241854b 
llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x241854b)
#39 0x0000000002eb95cd 
clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>,
 std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#40 0x0000000002e748ef 
clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, 
clang::driver::Command const*&, bool) const 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2e748ef)
#41 0x0000000002e758ef 
clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, 
llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) 
const 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2e758ef)
#42 0x0000000002e83815 
clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, 
llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0x2e83815)
#43 0x0000000000d3ad93 clang_main(int, char**, llvm::ToolContext const&) 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0xd3ad93)
#44 0x0000000000c10654 main 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0xc10654)
#45 0x00007efe29cf3681 __libc_start_call_main (/lib64/libc.so.6+0x3681)
#46 0x00007efe29cf3798 __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3798)
#47 0x0000000000d34be5 _start 
(/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin/clang+0xd34be5)
clang: error: clang frontend command failed due to signal (use -v to see 
invocation)
clang version 23.0.0git (https://github.com/kleisauke/llvm-project 
8c8189494b548b0fc6ba858701daae043c7b8306)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: 
/home/kleisauke/emsdk/llvm/git/build_wasm-function-pointers-rebase6_64/bin
Build config: +assertions
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/gsourceclosure-b0b801.c
clang: note: diagnostic msg: /tmp/gsourceclosure-b0b801.sh
clang: note: diagnostic msg: 

********************
```
</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