implement PR4077: [Linux kernel] inscrutable error on inline asm input/output constraint mismatch
Before we emitted:
$ clang t.c -S -m64
llvm: error: Unsupported asm: input constraint with a matching output constraint of incompatible type!
Now we produce:
$ clang t.c -S -m64
t.c:5:40: error: unsupported inline asm: input with type 'unsigned long' matching output with type 'int'
asm volatile("foo " : "=a" (a) :"0" (b));
~~~ ~^~
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70142 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index ad33ad3b..93e30ec 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -978,6 +978,24 @@
}
DefaultFunctionArrayConversion(Exprs[i]);
+
+ // 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
+ // same size (int/long, int*/long, are ok etc).
+ if (Info.hasTiedOperand()) {
+ unsigned TiedTo = Info.getTiedOperand();
+ QualType T1 = Exprs[TiedTo]->getType(), T2 = Exprs[i]->getType();
+ if (!Context.hasSameType(T1, T2)) {
+ // Int/ptr operands are ok if they are the same size.
+ if (!(T1->isIntegerType() || T1->isPointerType()) ||
+ !(T2->isIntegerType() || T2->isPointerType()) ||
+ Context.getTypeSize(T1) != Context.getTypeSize(T2))
+ return StmtError(Diag(InputExpr->getSubExpr()->getLocStart(),
+ diag::err_asm_tying_incompatible_types)
+ << T2 << T1 << Exprs[TiedTo]->getSourceRange()
+ << Exprs[i]->getSourceRange());
+ }
+ }
}
// Check that the clobbers are valid.