]> granicus.if.org Git - clang/commitdiff
[inlineasm] Fix an incorrect warning about register constraint and modifier.
authorAkira Hatanaka <ahatanaka@apple.com>
Wed, 4 Feb 2015 00:27:13 +0000 (00:27 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Wed, 4 Feb 2015 00:27:13 +0000 (00:27 +0000)
Previously, when the following piece of code was compiled, clang would
incorrectly warn that the size of "wide_two" does not match register size
specified by the constraint and modifier":

long wide_two = two;
asm ("%w0 %1" : "+r" (one), "+r"(wide_two));

This was caused by a miscalculation of ConstraintIdx in Sema::ActOnGCCAsmStmt.

This commit fixes PR21270 and rdar://problem/18668354.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228089 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmtAsm.cpp
test/Sema/inline-asm-validate-aarch64.c

index 1beac366c5081adadb02bdab966b1532d933c38f..c091cf88a92c3204e6c50255e3c7f6573a734c18 100644 (file)
@@ -313,32 +313,22 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
     if (!Piece.isOperand()) continue;
 
     // Look for the correct constraint index.
-    unsigned Idx = 0;
-    unsigned ConstraintIdx = 0;
-    for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) {
-      TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
-      if (Idx == Piece.getOperandNo())
-        break;
-      ++Idx;
-
-      if (Info.isReadWrite()) {
-        if (Idx == Piece.getOperandNo())
-          break;
-        ++Idx;
-      }
-    }
+    unsigned ConstraintIdx = Piece.getOperandNo();
+    unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs();
 
-    for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) {
-      TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
-      if (Idx == Piece.getOperandNo())
-        break;
-      ++Idx;
+    // Look for the (ConstraintIdx - NumOperands + 1)th constraint with
+    // modifier '+'.
+    if (ConstraintIdx >= NumOperands) {
+      unsigned I = 0, E = NS->getNumOutputs();
 
-      if (Info.isReadWrite()) {
-        if (Idx == Piece.getOperandNo())
+      for (unsigned Cnt = ConstraintIdx - NumOperands; I != E; ++I)
+        if (OutputConstraintInfos[I].isReadWrite() && Cnt-- == 0) {
+          ConstraintIdx = I;
           break;
-        ++Idx;
-      }
+        }
+
+      assert(I != E && "Invalid operand number should have been caught in "
+                       " AnalyzeAsmString");
     }
 
     // Now that we have the right indexes go ahead and check.
index 1364b6421eb0428a0672827146f5ef0641de3ed1..014767d5a3923e902c6d2069e0898f16a550d322 100644 (file)
@@ -36,3 +36,19 @@ uint8_t constraint_r_symbolic_macro(uint8_t *addr) {
 
   return byte;
 }
+
+// CHECK: warning: value size does not match register size specified by the constraint and modifier
+// CHECK: asm ("%w0 %w1 %2" : "+r" (one) : "r" (wide_two));
+// CHECK: note: use constraint modifier "w"
+// CHECK: fix-it:{{.*}}:{47:17-47:19}:"%w2"
+
+void read_write_modifier0(int one, int two) {
+  long wide_two = two;
+  asm ("%w0 %w1 %2" : "+r" (one) : "r" (wide_two));
+}
+
+// CHECK-NOT: warning: 
+void read_write_modifier1(int one, int two) {
+  long wide_two = two;
+  asm ("%w0 %1" : "+r" (one), "+r" (wide_two));
+}