diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -393,30 +393,31 @@ 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 --- /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)); +}