summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2015-01-06 04:26:34 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2015-01-06 04:26:34 +0000
commit9e0e86b228ebc6c50e4980ab45101d347a2f8f28 (patch)
tree3da4b8a9b762886f2c23dc15e8d087a366a904ac /include
parent94b0e1bbde5e930ec51d5f922928c07c82a943f8 (diff)
Sema: analyze I,J,K,M,N,O constraints
Add additional constraint checking for target specific behaviour for inline assembly constraints. We would previously silently let all arguments through for these constraints. In cases where the constraints were violated, we could end up failing to select instructions and triggering assertions or worse, silently ignoring instructions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225244 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Basic/TargetInfo.h24
2 files changed, 22 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 69f86b9692..d3129bd62e 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6178,6 +6178,8 @@ let CategoryName = "Inline Assembly Issue" in {
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
+ def err_invalid_asm_value_for_constraint
+ : Error <"value '%0' out of range for constraint '%1'">;
def warn_asm_label_on_auto_decl : Warning<
"ignored asm label '%0' on automatic variable">;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index f952d6d1d0..0ebd9c8be7 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -528,18 +528,23 @@ public:
CI_None = 0x00,
CI_AllowsMemory = 0x01,
CI_AllowsRegister = 0x02,
- CI_ReadWrite = 0x04, // "+r" output constraint (read and write).
- CI_HasMatchingInput = 0x08 // This output operand has a matching input.
+ 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
};
unsigned Flags;
int TiedOperand;
+ struct {
+ int Min;
+ int Max;
+ } ImmRange;
std::string ConstraintStr; // constraint: "=rm"
std::string Name; // Operand name: [foo] with no []'s.
public:
ConstraintInfo(StringRef ConstraintStr, StringRef Name)
- : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
- Name(Name.str()) {}
+ : Flags(0), TiedOperand(-1), ImmRange({0, 0}),
+ ConstraintStr(ConstraintStr.str()), Name(Name.str()) {}
const std::string &getConstraintStr() const { return ConstraintStr; }
const std::string &getName() const { return Name; }
@@ -562,10 +567,21 @@ public:
return (unsigned)TiedOperand;
}
+ bool requiresImmediateConstant() const {
+ return (Flags & CI_ImmediateConstant) != 0;
+ }
+ int getImmConstantMin() const { return ImmRange.Min; }
+ int getImmConstantMax() const { return ImmRange.Max; }
+
void setIsReadWrite() { Flags |= CI_ReadWrite; }
void setAllowsMemory() { Flags |= CI_AllowsMemory; }
void setAllowsRegister() { Flags |= CI_AllowsRegister; }
void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
+ void setRequiresImmediate(int Min, int Max) {
+ Flags |= CI_ImmediateConstant;
+ ImmRange.Min = Min;
+ ImmRange.Max = Max;
+ }
/// \brief Indicate that this is an input operand that is tied to
/// the specified output operand.