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.