From fe177a1773e4f88dde1aa37d34a0d3f8cb582f14 Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Fri, 27 Aug 2021 13:37:34 -0400 Subject: [PATCH] Fix assertion when passing function into inline asm's input operand This seem to be a regression caused by this change: https://reviews.llvm.org/D60943. Since we delayed report the error, we would run into some invalid state in clang and llvm. Without this fix, clang would assert when passing function into inline asm's input operand. Differential Revision: https://reviews.llvm.org/D107941 --- clang/lib/Sema/SemaStmtAsm.cpp | 39 +++++++++++++++++++------------------- clang/test/CodeGen/asm-call-func.c | 7 +++++++ 2 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 clang/test/CodeGen/asm-call-func.c diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 243d0b9..603611b 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -393,30 +393,31 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, diag::err_asm_invalid_lvalue_in_input) << Info.getConstraintStr() << InputExpr->getSourceRange()); - } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { - if (!InputExpr->isValueDependent()) { - Expr::EvalResult EVResult; - if (InputExpr->EvaluateAsRValue(EVResult, Context, true)) { - // For compatibility with GCC, we also allow pointers that would be - // integral constant expressions if they were cast to int. - llvm::APSInt IntResult; - if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), - Context)) - if (!Info.isValidAsmImmediate(IntResult)) - return StmtError(Diag(InputExpr->getBeginLoc(), - diag::err_invalid_asm_value_for_constraint) - << toString(IntResult, 10) - << Info.getConstraintStr() - << InputExpr->getSourceRange()); - } - } - } else { ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]); if (Result.isInvalid()) return StmtError(); - Exprs[i] = Result.get(); + InputExpr = Exprs[i] = Result.get(); + + if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { + if (!InputExpr->isValueDependent()) { + Expr::EvalResult EVResult; + if (InputExpr->EvaluateAsRValue(EVResult, Context, true)) { + // For compatibility with GCC, we also allow pointers that would be + // integral constant expressions if they were cast to int. + llvm::APSInt IntResult; + if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), + Context)) + if (!Info.isValidAsmImmediate(IntResult)) + return StmtError( + Diag(InputExpr->getBeginLoc(), + diag::err_invalid_asm_value_for_constraint) + << toString(IntResult, 10) << Info.getConstraintStr() + << InputExpr->getSourceRange()); + } + } + } } if (Info.allowsRegister()) { diff --git a/clang/test/CodeGen/asm-call-func.c b/clang/test/CodeGen/asm-call-func.c new file mode 100644 index 0000000..851dcc0 --- /dev/null +++ b/clang/test/CodeGen/asm-call-func.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu| FileCheck %s + +void callee(void); +void caller() { + //CHECK: call void asm sideeffect "rcall $0", "n,~{dirflag},~{fpsr},~{flags}"(void ()* @callee) + asm("rcall %0" ::"n"(callee)); +} -- 2.7.4