From f76d3b800f7341882ea93db47cc8f28d94e74f1c Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Wed, 2 Mar 2022 11:18:54 -0800 Subject: [PATCH] [clang][CGStmt] fix crash on invalid asm statement Clang is crashing on the following statement char var[9]; __asm__ ("" : "=r" (var) : "0" (var)); This is similar to existing test: crbug_999160_regtest The issue happens when EmitAsmStmt is trying to convert input to match output type length. However, that is not guaranteed to be successful all the time and if the statement itself is invalid like having an array type in the example, we should give a regular error message here instead of using assert(). Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D120596 --- clang/lib/CodeGen/CGStmt.cpp | 4 +--- clang/test/CodeGen/X86/x86_64-PR42672.c | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 011909a5834b..01ccc7146306 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2518,10 +2518,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Arg = Builder.CreateZExt(Arg, OutputTy); else if (isa(OutputTy)) Arg = Builder.CreateZExt(Arg, IntPtrTy); - else { - assert(OutputTy->isFloatingPointTy() && "Unexpected output type"); + else if (OutputTy->isFloatingPointTy()) Arg = Builder.CreateFPExt(Arg, OutputTy); - } } // Deal with the tied operands' constraint code in adjustInlineAsmType. ReplaceConstraint = OutputConstraints[Output]; diff --git a/clang/test/CodeGen/X86/x86_64-PR42672.c b/clang/test/CodeGen/X86/x86_64-PR42672.c index 2e8ec15b5852..6eea20a1e3f6 100644 --- a/clang/test/CodeGen/X86/x86_64-PR42672.c +++ b/clang/test/CodeGen/X86/x86_64-PR42672.c @@ -5,6 +5,7 @@ // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-X // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_X // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES +// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES_V2 -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES_V2 // Make sure Clang doesn't treat |lockval| as asm input. void _raw_spin_lock(void) { @@ -115,3 +116,11 @@ void crbug_999160_regtest(void) { } // CHECK-IMPOSSIBLE_9BYTES: impossible constraint in asm: can't store value into a register + +void crbug_999160_regtest_v2(void) { +#ifdef IMPOSSIBLE_9BYTES_V2 + char buf[9]; + asm("" : "=r"(buf) : "0"(buf)); +#endif +} +// CHECK-IMPOSSIBLE_9BYTES_V2: impossible constraint in asm: can't store value into a register