Prohibit capture of _ExtInt in inline assembly.
The backends don't seem to properly handle the _ExtInt type in inline assembly with crashes occurring in many. While the ones I tested seem to work for powers of 2 < 64 (and some any multiple of 64 greater than that), it seemed like a better idea to just use of this type in inline assembly prohibited.
This commit is contained in:
@@ -240,6 +240,9 @@ let CategoryName = "Inline Assembly Issue" in {
|
||||
def err_asm_invalid_type_in_input : Error<
|
||||
"invalid type %0 in asm input for constraint '%1'">;
|
||||
|
||||
def err_asm_invalid_type : Error<
|
||||
"invalid type %0 in asm %select{input|output}1">;
|
||||
|
||||
def warn_stack_clash_protection_inline_asm : Warning<
|
||||
"Unable to protect inline asm that clobbers stack pointer against stack clash">,
|
||||
InGroup<DiagGroup<"stack-protector">>;
|
||||
|
||||
@@ -296,6 +296,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
||||
checkExprMemoryConstraintCompat(*this, OutputExpr, Info, false))
|
||||
return StmtError();
|
||||
|
||||
// Disallow _ExtInt, since the backends tend to have difficulties with
|
||||
// non-normal sizes.
|
||||
if (OutputExpr->getType()->isExtIntType())
|
||||
return StmtError(
|
||||
Diag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_type)
|
||||
<< OutputExpr->getType() << 0 /*Input*/
|
||||
<< OutputExpr->getSourceRange());
|
||||
|
||||
OutputConstraintInfos.push_back(Info);
|
||||
|
||||
// If this is dependent, just continue.
|
||||
@@ -420,6 +428,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
||||
}
|
||||
}
|
||||
|
||||
if (InputExpr->getType()->isExtIntType())
|
||||
return StmtError(
|
||||
Diag(InputExpr->getBeginLoc(), diag::err_asm_invalid_type)
|
||||
<< InputExpr->getType() << 1 /*Output*/
|
||||
<< InputExpr->getSourceRange());
|
||||
|
||||
InputConstraintInfos.push_back(Info);
|
||||
|
||||
const Type *Ty = Exprs[i]->getType().getTypePtr();
|
||||
@@ -892,6 +906,15 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
|
||||
SourceLocation EndLoc) {
|
||||
bool IsSimple = (NumOutputs != 0 || NumInputs != 0);
|
||||
setFunctionHasBranchProtectedScope();
|
||||
|
||||
for (uint64_t I = 0; I < NumOutputs + NumInputs; ++I) {
|
||||
if (Exprs[I]->getType()->isExtIntType())
|
||||
return StmtError(
|
||||
Diag(Exprs[I]->getBeginLoc(), diag::err_asm_invalid_type)
|
||||
<< Exprs[I]->getType() << (I < NumOutputs)
|
||||
<< Exprs[I]->getSourceRange());
|
||||
}
|
||||
|
||||
MSAsmStmt *NS =
|
||||
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
|
||||
/*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple x86_64-gnu-linux
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple x86_64-gnu-linux -fasm-blocks
|
||||
|
||||
template<int Bounds>
|
||||
struct HasExtInt {
|
||||
@@ -276,3 +276,12 @@ void ImplicitCasts(_ExtInt(31) s31, _ExtInt(33) s33, int i) {
|
||||
i = s33;
|
||||
}
|
||||
|
||||
|
||||
void NotAllowedInInlineAsm(_ExtInt(9) in, _ExtInt(9) out) {
|
||||
__asm { mov eax, in} // expected-error{{invalid type '_ExtInt(9)' in asm input}}
|
||||
__asm { mov out, eax} // expected-error{{invalid type '_ExtInt(9)' in asm output}}
|
||||
|
||||
asm("" : "=g" (in));// expected-error{{invalid type '_ExtInt(9)' in asm input}}
|
||||
asm("" :: "r" (out));// expected-error{{invalid type '_ExtInt(9)' in asm output}}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user