r225586 - Sema: The asm constraint '+&m' isn't valid, reject it

David Majnemer david.majnemer at gmail.com
Sat Jan 10 02:43:19 PST 2015


Author: majnemer
Date: Sat Jan 10 04:43:19 2015
New Revision: 225586

URL: http://llvm.org/viewvc/llvm-project?rev=225586&view=rev
Log:
Sema: The asm constraint '+&m' isn't valid, reject it

Don't permit '+&m' to make it to CodeGen, it's invalid.

Modified:
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/Basic/TargetInfo.cpp
    cfe/trunk/test/Sema/asm.c

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=225586&r1=225585&r2=225586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Sat Jan 10 04:43:19 2015
@@ -531,6 +531,7 @@ public:
       CI_ReadWrite = 0x04,         // "+r" output constraint (read and write).
       CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
       CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
+      CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
     };
     unsigned Flags;
     int TiedOperand;
@@ -551,6 +552,7 @@ public:
     const std::string &getConstraintStr() const { return ConstraintStr; }
     const std::string &getName() const { return Name; }
     bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
+    bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
     bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
     bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
 
@@ -576,6 +578,7 @@ public:
     int getImmConstantMax() const { return ImmRange.Max; }
 
     void setIsReadWrite() { Flags |= CI_ReadWrite; }
+    void setEarlyClobber() { Flags |= CI_EarlyClobber; }
     void setAllowsMemory() { Flags |= CI_AllowsMemory; }
     void setAllowsRegister() { Flags |= CI_AllowsRegister; }
     void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }

Modified: cfe/trunk/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=225586&r1=225585&r2=225586&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/TargetInfo.cpp (original)
+++ cfe/trunk/lib/Basic/TargetInfo.cpp Sat Jan 10 04:43:19 2015
@@ -459,7 +459,9 @@ bool TargetInfo::validateOutputConstrain
         // Eventually, an unknown constraint should just be treated as 'g'.
         return false;
       }
+      break;
     case '&': // early clobber.
+      Info.setEarlyClobber();
       break;
     case '%': // commutative.
       // FIXME: Check that there is a another register after this one.
@@ -494,6 +496,11 @@ bool TargetInfo::validateOutputConstrain
     Name++;
   }
 
+  // Early clobber with a read-write constraint which doesn't permit registers
+  // is invalid.
+  if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
+    return false;
+
   // If a constraint allows neither memory nor register operands it contains
   // only modifiers. Reject it.
   return Info.allowsMemory() || Info.allowsRegister();

Modified: cfe/trunk/test/Sema/asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/asm.c?rev=225586&r1=225585&r2=225586&view=diff
==============================================================================
--- cfe/trunk/test/Sema/asm.c (original)
+++ cfe/trunk/test/Sema/asm.c Sat Jan 10 04:43:19 2015
@@ -171,3 +171,9 @@ void fn1() {
           : [l] "=r"(l)
           : "[l],m"(l)); // expected-error {{asm constraint has an unexpected number of alternatives: 1 vs 2}}
 }
+
+void fn2() {
+  int l;
+ __asm__(""
+          : "+&m"(l)); // expected-error {{invalid output constraint '+&m' in asm}}
+}





More information about the cfe-commits mailing list