mirror of https://github.com/microsoft/clang.git
[X86, inlineasm] Check that the output size is correct for the given constraint.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218064 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
03b182422a
commit
cd588f07da
|
@ -6051,6 +6051,8 @@ let CategoryName = "Inline Assembly Issue" in {
|
|||
def err_asm_bad_register_type : Error<"bad type for named register variable">;
|
||||
def err_asm_invalid_input_size : Error<
|
||||
"invalid input size for constraint '%0'">;
|
||||
def err_asm_invalid_output_size : Error<
|
||||
"invalid output size for constraint '%0'">;
|
||||
def err_invalid_asm_cast_lvalue : Error<
|
||||
"invalid use of a cast in a inline asm context requiring an l-value: "
|
||||
"remove the cast or build with -fheinous-gnu-extensions">;
|
||||
|
|
|
@ -577,6 +577,12 @@ public:
|
|||
bool validateInputConstraint(ConstraintInfo *OutputConstraints,
|
||||
unsigned NumOutputs,
|
||||
ConstraintInfo &info) const;
|
||||
|
||||
virtual bool validateOutputSize(StringRef /*Constraint*/,
|
||||
unsigned /*Size*/) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool validateInputSize(StringRef /*Constraint*/,
|
||||
unsigned /*Size*/) const {
|
||||
return true;
|
||||
|
|
|
@ -1901,8 +1901,12 @@ public:
|
|||
bool validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &info) const override;
|
||||
|
||||
bool validateOutputSize(StringRef Constraint, unsigned Size) const override;
|
||||
|
||||
bool validateInputSize(StringRef Constraint, unsigned Size) const override;
|
||||
|
||||
virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
|
||||
|
||||
std::string convertConstraint(const char *&Constraint) const override;
|
||||
const char *getClobbers() const override {
|
||||
return "~{dirflag},~{fpsr},~{flags}";
|
||||
|
@ -3053,8 +3057,24 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
|
|||
}
|
||||
}
|
||||
|
||||
bool X86TargetInfo::validateOutputSize(StringRef Constraint,
|
||||
unsigned Size) const {
|
||||
// Strip off constraint modifiers.
|
||||
while (Constraint[0] == '=' ||
|
||||
Constraint[0] == '+' ||
|
||||
Constraint[0] == '&')
|
||||
Constraint = Constraint.substr(1);
|
||||
|
||||
return validateOperandSize(Constraint, Size);
|
||||
}
|
||||
|
||||
bool X86TargetInfo::validateInputSize(StringRef Constraint,
|
||||
unsigned Size) const {
|
||||
return validateOperandSize(Constraint, Size);
|
||||
}
|
||||
|
||||
bool X86TargetInfo::validateOperandSize(StringRef Constraint,
|
||||
unsigned Size) const {
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'y':
|
||||
|
@ -3124,8 +3144,8 @@ public:
|
|||
if (RegNo == 1) return 2;
|
||||
return -1;
|
||||
}
|
||||
bool validateInputSize(StringRef Constraint,
|
||||
unsigned Size) const override {
|
||||
bool validateOperandSize(StringRef Constraint,
|
||||
unsigned Size) const override {
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'R':
|
||||
|
@ -3142,7 +3162,7 @@ public:
|
|||
return Size <= 64;
|
||||
}
|
||||
|
||||
return X86TargetInfo::validateInputSize(Constraint, Size);
|
||||
return X86TargetInfo::validateOperandSize(Constraint, Size);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
|
|
@ -121,6 +121,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|||
return StmtError();
|
||||
|
||||
OutputConstraintInfos.push_back(Info);
|
||||
|
||||
const Type *Ty = OutputExpr->getType().getTypePtr();
|
||||
|
||||
// If this is a dependent type, just continue. We don't know the size of a
|
||||
// dependent type.
|
||||
if (Ty->isDependentType())
|
||||
continue;
|
||||
|
||||
unsigned Size = Context.getTypeSize(Ty);
|
||||
if (!Context.getTargetInfo().validateOutputSize(Literal->getString(),
|
||||
Size))
|
||||
return StmtError(Diag(OutputExpr->getLocStart(),
|
||||
diag::err_asm_invalid_output_size)
|
||||
<< Info.getConstraintStr());
|
||||
}
|
||||
|
||||
SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
|
||||
|
|
|
@ -5,8 +5,8 @@ vec256 foo(vec256 in) {
|
|||
vec256 out;
|
||||
|
||||
asm("something %0" : : "y"(in)); // expected-error {{invalid input size for constraint 'y'}}
|
||||
asm("something %0" : "=y"(out));
|
||||
asm("something %0, %0" : "+y"(out));
|
||||
asm("something %0" : "=y"(out)); // expected-error {{invalid output size for constraint '=y'}}
|
||||
asm("something %0, %0" : "+y"(out)); // expected-error {{invalid output size for constraint '+y'}}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -43,4 +43,17 @@ int func1() {
|
|||
__asm__ volatile("foo1 %0" : : "f" (val256)); // expected-error {{invalid input size for constraint 'f'}}
|
||||
__asm__ volatile("foo1 %0" : : "t" (val256)); // expected-error {{invalid input size for constraint 't'}}
|
||||
__asm__ volatile("foo1 %0" : : "u" (val256)); // expected-error {{invalid input size for constraint 'u'}}
|
||||
|
||||
__asm__ volatile("foo1 %0" : "=R" (val)); // expected-error {{invalid output size for constraint '=R'}}
|
||||
__asm__ volatile("foo1 %0" : "=q" (val)); // expected-error {{invalid output size for constraint '=q'}}
|
||||
__asm__ volatile("foo1 %0" : "=Q" (val)); // expected-error {{invalid output size for constraint '=Q'}}
|
||||
__asm__ volatile("foo1 %0" : "=a" (val)); // expected-error {{invalid output size for constraint '=a'}}
|
||||
__asm__ volatile("foo1 %0" : "=b" (val)); // expected-error {{invalid output size for constraint '=b'}}
|
||||
__asm__ volatile("foo1 %0" : "=c" (val)); // expected-error {{invalid output size for constraint '=c'}}
|
||||
__asm__ volatile("foo1 %0" : "=d" (val)); // expected-error {{invalid output size for constraint '=d'}}
|
||||
__asm__ volatile("foo1 %0" : "=S" (val)); // expected-error {{invalid output size for constraint '=S'}}
|
||||
__asm__ volatile("foo1 %0" : "=D" (val)); // expected-error {{invalid output size for constraint '=D'}}
|
||||
__asm__ volatile("foo1 %0" : "=A" (val128)); // expected-error {{invalid output size for constraint '=A'}}
|
||||
__asm__ volatile("foo1 %0" : "=t" (val256)); // expected-error {{invalid output size for constraint '=t'}}
|
||||
__asm__ volatile("foo1 %0" : "=u" (val256)); // expected-error {{invalid output size for constraint '=u'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue