Sema: Forbid inconsistent constraint alternatives
Verify that asm constraints have the same number of alternatives llvm-svn: 224911
This commit is contained in:
parent
c52f300698
commit
c63fa612e4
|
@ -6166,6 +6166,8 @@ let CategoryName = "Inline Assembly Issue" in {
|
||||||
def err_asm_tying_incompatible_types : Error<
|
def err_asm_tying_incompatible_types : Error<
|
||||||
"unsupported inline asm: input with type "
|
"unsupported inline asm: input with type "
|
||||||
"%diff{$ matching output with type $|}0,1">;
|
"%diff{$ matching output with type $|}0,1">;
|
||||||
|
def err_asm_unexpected_constraint_alternatives : Error<
|
||||||
|
"asm constraint has an unexpected number of alternatives: %0 vs %1">;
|
||||||
def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
|
def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
|
||||||
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
|
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
|
||||||
def err_asm_bad_register_type : Error<"bad type for named register variable">;
|
def err_asm_bad_register_type : Error<"bad type for named register variable">;
|
||||||
|
|
|
@ -317,8 +317,28 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate tied input operands for type mismatches.
|
// Validate tied input operands for type mismatches.
|
||||||
|
unsigned NumAlternatives = ~0U;
|
||||||
|
for (unsigned i = 0, e = OutputConstraintInfos.size(); i != e; ++i) {
|
||||||
|
TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
|
||||||
|
StringRef ConstraintStr = Info.getConstraintStr();
|
||||||
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
||||||
|
if (NumAlternatives == ~0U)
|
||||||
|
NumAlternatives = AltCount;
|
||||||
|
else if (NumAlternatives != AltCount)
|
||||||
|
return StmtError(Diag(NS->getOutputExpr(i)->getLocStart(),
|
||||||
|
diag::err_asm_unexpected_constraint_alternatives)
|
||||||
|
<< NumAlternatives << AltCount);
|
||||||
|
}
|
||||||
for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
|
for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
|
||||||
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
|
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
|
||||||
|
StringRef ConstraintStr = Info.getConstraintStr();
|
||||||
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
||||||
|
if (NumAlternatives == ~0U)
|
||||||
|
NumAlternatives = AltCount;
|
||||||
|
else if (NumAlternatives != AltCount)
|
||||||
|
return StmtError(Diag(NS->getInputExpr(i)->getLocStart(),
|
||||||
|
diag::err_asm_unexpected_constraint_alternatives)
|
||||||
|
<< NumAlternatives << AltCount);
|
||||||
|
|
||||||
// If this is a tied constraint, verify that the output and input have
|
// If this is a tied constraint, verify that the output and input have
|
||||||
// either exactly the same type, or that they are int/ptr operands with the
|
// either exactly the same type, or that they are int/ptr operands with the
|
||||||
|
|
|
@ -164,3 +164,10 @@ double f_output_constraint(void) {
|
||||||
__asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}}
|
__asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fn1() {
|
||||||
|
int l;
|
||||||
|
__asm__(""
|
||||||
|
: [l] "=r"(l)
|
||||||
|
: "[l],m"(l)); // expected-error {{asm constraint has an unexpected number of alternatives: 1 vs 2}}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue