Skip to content

Commit 7681975

Browse files
committed
Merging r354937:
------------------------------------------------------------------------ r354937 | joerg | 2019-02-27 01:40:59 +0100 (Wed, 27 Feb 2019) | 9 lines Fix inline assembler constraint validation The current constraint logic is both too lax and too strict. It fails for input outside the [INT_MIN..INT_MAX] range, but it also implicitly accepts 0 as value when it should not. Adjust logic to handle both correctly. Differential Revision: https://reviews.llvm.org/D58649 ------------------------------------------------------------------------ llvm-svn: 355673
1 parent 0a0560b commit 7681975

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
807807
struct {
808808
int Min;
809809
int Max;
810+
bool isConstrained;
810811
} ImmRange;
811812
llvm::SmallSet<int, 4> ImmSet;
812813

@@ -817,6 +818,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
817818
: Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
818819
Name(Name.str()) {
819820
ImmRange.Min = ImmRange.Max = 0;
821+
ImmRange.isConstrained = false;
820822
}
821823

822824
const std::string &getConstraintStr() const { return ConstraintStr; }
@@ -845,8 +847,9 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
845847
return (Flags & CI_ImmediateConstant) != 0;
846848
}
847849
bool isValidAsmImmediate(const llvm::APInt &Value) const {
848-
return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) ||
849-
ImmSet.count(Value.getZExtValue()) != 0;
850+
if (!ImmSet.empty())
851+
return ImmSet.count(Value.getZExtValue()) != 0;
852+
return !ImmRange.isConstrained || (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
850853
}
851854

852855
void setIsReadWrite() { Flags |= CI_ReadWrite; }
@@ -858,6 +861,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
858861
Flags |= CI_ImmediateConstant;
859862
ImmRange.Min = Min;
860863
ImmRange.Max = Max;
864+
ImmRange.isConstrained = true;
861865
}
862866
void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
863867
Flags |= CI_ImmediateConstant;
@@ -870,8 +874,6 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
870874
}
871875
void setRequiresImmediate() {
872876
Flags |= CI_ImmediateConstant;
873-
ImmRange.Min = INT_MIN;
874-
ImmRange.Max = INT_MAX;
875877
}
876878

877879
/// Indicate that this is an input operand that is tied to

clang/test/Sema/inline-asm-validate-x86.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void K(int i, int j) {
5555
void L(int i, int j) {
5656
static const int Invalid1 = 1;
5757
static const int Invalid2 = 42;
58+
static const int Invalid3 = 0;
5859
static const int Valid1 = 0xff;
5960
static const int Valid2 = 0xffff;
6061
static const int Valid3 = 0xffffffff;
@@ -67,6 +68,9 @@ void L(int i, int j) {
6768
__asm__("xorl %0,%2"
6869
: "=r"(i)
6970
: "0"(i), "L"(Invalid2)); // expected-error{{value '42' out of range for constraint 'L'}}
71+
__asm__("xorl %0,%2"
72+
: "=r"(i)
73+
: "0"(i), "L"(Invalid3)); // expected-error{{value '0' out of range for constraint 'L'}}
7074
__asm__("xorl %0,%2"
7175
: "=r"(i)
7276
: "0"(i), "L"(Valid1)); // expected-no-error

0 commit comments

Comments
 (0)