Skip to content

Commit

Permalink
[Verifier] Reject va_start in non-variadic function (#88809)
Browse files Browse the repository at this point in the history
A va_start intrinsic lowers to something derived from the variadic
parameter to the function. If there is no such parameter, it can't lower
meaningfully. Clang sema rejects the same with `error: 'va_start' used
in function with fixed args`.

Moves the existing lint warning into a verifier error. Updates the one
lit test that had a va_start in a non-variadic function.
  • Loading branch information
JonChesterfield authored Apr 16, 2024
1 parent 76782e2 commit 61717c1
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 12 deletions.
5 changes: 1 addition & 4 deletions llvm/lib/Analysis/Lint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,7 @@ void Lint::visitCallBase(CallBase &I) {
}

case Intrinsic::vastart:
Check(I.getParent()->getParent()->isVarArg(),
"Undefined behavior: va_start called in a non-varargs function",
&I);

// vastart in non-varargs function is rejected by the verifier
visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI),
std::nullopt, nullptr, MemRef::Read | MemRef::Write);
break;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5798,6 +5798,11 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {

break;
}
case Intrinsic::vastart: {
Check(Call.getFunction()->isVarArg(),
"va_start called in a non-varargs function");
break;
}
case Intrinsic::vector_reduce_and:
case Intrinsic::vector_reduce_or:
case Intrinsic::vector_reduce_xor:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AArch64/GlobalISel/vastart.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


declare void @llvm.va_start(ptr)
define void @test_va_start(ptr %list) {
define void @test_va_start(ptr %list, ...) {
; CHECK-LABEL: name: test_va_start
; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0
; CHECK-IOS: G_VASTART [[LIST]](p0) :: (store (s64) into %ir.list, align 1)
Expand Down
7 changes: 0 additions & 7 deletions llvm/test/Other/lint.ll
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,6 @@ define void @0() nounwind {
ret void
}

; CHECK: va_start called in a non-varargs function
declare void @llvm.va_start(ptr)
define void @not_vararg(ptr %p) nounwind {
call void @llvm.va_start(ptr %p)
ret void
}

; CHECK: Undefined behavior: Branch to non-blockaddress
define void @use_indbr() {
indirectbr ptr @foo, [label %block]
Expand Down
8 changes: 8 additions & 0 deletions llvm/test/Verifier/variadic.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; RUN: not opt -S -passes=verify 2>&1 < %s | FileCheck %s

; CHECK: va_start called in a non-varargs function
declare void @llvm.va_start(ptr)
define void @not_vararg(ptr %p) nounwind {
call void @llvm.va_start(ptr %p)
ret void
}

0 comments on commit 61717c1

Please sign in to comment.