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