forked from OSchip/llvm-project
Check that the input size is correct for the given constraint.
The 'a', 'c', and 'd' constraints on i386 mean a 32-bit register. We cannot place a 64-bit value into the 32-bit register. Error out instead of causing the compiler to spew general badness. <rdar://problem/12415959> llvm-svn: 167717
This commit is contained in:
parent
b41000ed70
commit
887b485dbe
clang
include/clang/Basic
lib
test/CodeGen
|
@ -5141,6 +5141,8 @@ let CategoryName = "Inline Assembly Issue" in {
|
|||
"%diff{$ matching output with type $|}0,1">;
|
||||
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
|
||||
def err_asm_empty : Error<"__asm used with no assembly instructions">;
|
||||
def err_asm_invalid_input_size : Error<
|
||||
"invalid input 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">;
|
||||
|
|
|
@ -517,6 +517,10 @@ public:
|
|||
bool validateInputConstraint(ConstraintInfo *OutputConstraints,
|
||||
unsigned NumOutputs,
|
||||
ConstraintInfo &info) const;
|
||||
virtual bool validateInputSize(StringRef /*Constraint*/,
|
||||
unsigned /*Size*/) const {
|
||||
return true;
|
||||
}
|
||||
virtual bool validateConstraintModifier(StringRef /*Constraint*/,
|
||||
const char /*Modifier*/,
|
||||
unsigned /*Size*/) const {
|
||||
|
|
|
@ -2595,6 +2595,19 @@ public:
|
|||
if (RegNo == 1) return 2;
|
||||
return -1;
|
||||
}
|
||||
virtual bool validateInputSize(StringRef Constraint,
|
||||
unsigned Size) const {
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
return Size == 32;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
|
|
@ -179,6 +179,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|||
|
||||
Exprs[i] = Result.take();
|
||||
InputConstraintInfos.push_back(Info);
|
||||
|
||||
const Type *Ty = Exprs[i]->getType().getTypePtr();
|
||||
if (Ty->isDependentType() || Ty->isIncompleteType())
|
||||
continue;
|
||||
|
||||
unsigned Size = Context.getTypeSize(Ty);
|
||||
if (!Context.getTargetInfo().validateInputSize(Literal->getString(),
|
||||
Size))
|
||||
return StmtError(Diag(InputExpr->getLocStart(),
|
||||
diag::err_asm_invalid_input_size)
|
||||
<< Info.getConstraintStr());
|
||||
}
|
||||
|
||||
// Check that the clobbers are valid.
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: %clang_cc1 -triple i386-apple-darwin9 -verify %s
|
||||
// <rdar://problem/12415959>
|
||||
|
||||
typedef unsigned int u_int32_t;
|
||||
typedef u_int32_t uint32_t;
|
||||
|
||||
typedef unsigned long long u_int64_t;
|
||||
typedef u_int64_t uint64_t;
|
||||
|
||||
int main () {
|
||||
uint32_t msr = 0x8b;
|
||||
uint64_t val = 0;
|
||||
__asm__ volatile("wrmsr"
|
||||
:
|
||||
: "c" (msr),
|
||||
"a" ((val & 0xFFFFFFFFUL)), // expected-error {{invalid input size for constraint 'a'}}
|
||||
"d" (((val >> 32) & 0xFFFFFFFFUL)));
|
||||
}
|
Loading…
Reference in New Issue