[clang] [Clang][CodeGen][CUDA] Add missing null-check assertions in CGCUDARuntime (PR #181167)
Giovanni B. via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 12 10:26:01 PST 2026
https://github.com/Z3rox-dev updated https://github.com/llvm/llvm-project/pull/181167
>From 8c658675c36730e3ecfc7dac00d23c7ba4c6bc57 Mon Sep 17 00:00:00 2001
From: Giovanni Baldon <116344382+Z3rox-dev at users.noreply.github.com>
Date: Thu, 12 Feb 2026 16:37:58 +0100
Subject: [PATCH] [Clang][CodeGen][CUDA] Add missing null-check assertions in
CGCUDARuntime
Add defensive assert checks for all getAs<>() calls in
CGCUDARuntime.cpp that were previously dereferenced without any
null verification.
The file had 8 unchecked getAs<>() calls across emitGetParamBuf()
and EmitCUDADeviceKernelCallExpr(), including chained dereferences
where a null return would cause an immediate crash.
This also eliminates redundant getAs<>() calls by caching the
result in local variables (LaunchFPT, KernelFPT), which is both
safer and more efficient.
While Sema validation currently prevents these types from being
null in practice, adding assertions follows the established
defensive coding pattern used elsewhere in CodeGen and improves
debuggability in assertion-enabled builds.
NFC (no functional change in release builds).
---
clang/lib/CodeGen/CGCUDARuntime.cpp | 32 ++++++++++++++---------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CodeGen/CGCUDARuntime.cpp b/clang/lib/CodeGen/CGCUDARuntime.cpp
index 9c831b26c3a7b..c1d5c8a40b34f 100644
--- a/clang/lib/CodeGen/CGCUDARuntime.cpp
+++ b/clang/lib/CodeGen/CGCUDARuntime.cpp
@@ -26,7 +26,7 @@ static llvm::Value *emitGetParamBuf(CodeGenFunction &CGF,
const CUDAKernelCallExpr *E) {
auto *GetParamBuf = CGF.getContext().getcudaGetParameterBufferDecl();
const FunctionProtoType *GetParamBufProto =
- GetParamBuf->getType()->getAs<FunctionProtoType>();
+ GetParamBuf->getType()->castAs<FunctionProtoType>();
DeclRefExpr *DRE = DeclRefExpr::Create(
CGF.getContext(), {}, {}, GetParamBuf,
@@ -42,9 +42,9 @@ static llvm::Value *emitGetParamBuf(CodeGenFunction &CGF,
Args.add(RValue::get(CGF.CGM.getSize(CharUnits::fromQuantity(64))),
CGF.getContext().getSizeType());
// Calculate parameter sizes.
- const PointerType *PT = E->getCallee()->getType()->getAs<PointerType>();
+ const PointerType *PT = E->getCallee()->getType()->castAs<PointerType>();
const FunctionProtoType *FTP =
- PT->getPointeeType()->getAs<FunctionProtoType>();
+ PT->getPointeeType()->castAs<FunctionProtoType>();
CharUnits Offset = CharUnits::Zero();
for (auto ArgTy : FTP->getParamTypes()) {
auto TInfo = CGF.CGM.getContext().getTypeInfoInChars(ArgTy);
@@ -79,14 +79,14 @@ RValue CGCUDARuntime::EmitCUDADeviceKernelCallExpr(
eval.begin(CGF);
CGF.EmitBlock(ConfigOKBlock);
- QualType KernelCalleeFuncTy =
- E->getCallee()->getType()->getAs<PointerType>()->getPointeeType();
+ const auto *KernelPT = E->getCallee()->getType()->castAs<PointerType>();
+ QualType KernelCalleeFuncTy = KernelPT->getPointeeType();
CGCallee KernelCallee = CGF.EmitCallee(E->getCallee());
// Emit kernel arguments.
CallArgList KernelCallArgs;
- CGF.EmitCallArgs(KernelCallArgs,
- KernelCalleeFuncTy->getAs<FunctionProtoType>(),
- E->arguments(), E->getDirectCallee());
+ const auto *KernelFPT = KernelCalleeFuncTy->castAs<FunctionProtoType>();
+ CGF.EmitCallArgs(KernelCallArgs, KernelFPT, E->arguments(),
+ E->getDirectCallee());
// Copy emitted kernel arguments into that parameter buffer.
RawAddress CfgBase(Config, CGM.Int8Ty,
/*Alignment=*/CharUnits::fromQuantity(64));
@@ -101,22 +101,20 @@ RValue CGCUDARuntime::EmitCUDADeviceKernelCallExpr(
}
// Make `cudaLaunchDevice` call, i.e. E->getConfig().
const CallExpr *LaunchCall = E->getConfig();
- QualType LaunchCalleeFuncTy = LaunchCall->getCallee()
- ->getType()
- ->getAs<PointerType>()
- ->getPointeeType();
+ const auto *LaunchPT =
+ LaunchCall->getCallee()->getType()->castAs<PointerType>();
+ QualType LaunchCalleeFuncTy = LaunchPT->getPointeeType();
CGCallee LaunchCallee = CGF.EmitCallee(LaunchCall->getCallee());
CallArgList LaunchCallArgs;
- CGF.EmitCallArgs(LaunchCallArgs,
- LaunchCalleeFuncTy->getAs<FunctionProtoType>(),
- LaunchCall->arguments(), LaunchCall->getDirectCallee());
+ const auto *LaunchFPT = LaunchCalleeFuncTy->castAs<FunctionProtoType>();
+ CGF.EmitCallArgs(LaunchCallArgs, LaunchFPT, LaunchCall->arguments(),
+ LaunchCall->getDirectCallee());
// Replace func and paramterbuffer arguments.
LaunchCallArgs[0] = CallArg(RValue::get(KernelCallee.getFunctionPointer()),
CGM.getContext().VoidPtrTy);
LaunchCallArgs[1] = CallArg(RValue::get(Config), CGM.getContext().VoidPtrTy);
const CGFunctionInfo &LaunchCallInfo = CGM.getTypes().arrangeFreeFunctionCall(
- LaunchCallArgs, LaunchCalleeFuncTy->getAs<FunctionProtoType>(),
- /*ChainCall=*/false);
+ LaunchCallArgs, LaunchFPT, /*ChainCall=*/false);
CGF.EmitCall(LaunchCallInfo, LaunchCallee, ReturnValue, LaunchCallArgs,
CallOrInvoke,
/*IsMustTail=*/false, E->getExprLoc());
More information about the cfe-commits
mailing list