diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-26 18:22:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-26 18:22:24 +0000 |
commit | 49ac88166d36f8c436780694f2ce955acde87c6a (patch) | |
tree | 2d5a8172e0411819f5374058c9678ebe1ce68623 /lib/Sema/SemaStmt.cpp | |
parent | d68876176a0d2c19e3864e7d38f6036c4f72f0a3 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index ad33ad3b20..93e30ec65f 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -978,6 +978,24 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, } 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. |