diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 6 | ||||
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CodeGen/mmx-inline-asm-error.c | 4 | ||||
| -rw-r--r-- | clang/test/CodeGen/x86_32-inline-asm.c | 13 |
6 files changed, 60 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7e08fce794a..163bceaaa2c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6051,6 +6051,8 @@ let CategoryName = "Inline Assembly Issue" in { def err_asm_bad_register_type : Error<"bad type for named register variable">; def err_asm_invalid_input_size : Error< "invalid input size for constraint '%0'">; + def err_asm_invalid_output_size : Error< + "invalid output size for constraint '%0'">; 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">; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index e26f595c3d3..8c2b89c736b 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -577,6 +577,12 @@ public: bool validateInputConstraint(ConstraintInfo *OutputConstraints, unsigned NumOutputs, ConstraintInfo &info) const; + + virtual bool validateOutputSize(StringRef /*Constraint*/, + unsigned /*Size*/) const { + return true; + } + virtual bool validateInputSize(StringRef /*Constraint*/, unsigned /*Size*/) const { return true; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 511817f324c..8ff30d9a048 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -1901,8 +1901,12 @@ public: bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; + bool validateOutputSize(StringRef Constraint, unsigned Size) const override; + bool validateInputSize(StringRef Constraint, unsigned Size) const override; + virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const; + std::string convertConstraint(const char *&Constraint) const override; const char *getClobbers() const override { return "~{dirflag},~{fpsr},~{flags}"; @@ -3053,8 +3057,24 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, } } +bool X86TargetInfo::validateOutputSize(StringRef Constraint, + unsigned Size) const { + // Strip off constraint modifiers. + while (Constraint[0] == '=' || + Constraint[0] == '+' || + Constraint[0] == '&') + Constraint = Constraint.substr(1); + + return validateOperandSize(Constraint, Size); +} + bool X86TargetInfo::validateInputSize(StringRef Constraint, unsigned Size) const { + return validateOperandSize(Constraint, Size); +} + +bool X86TargetInfo::validateOperandSize(StringRef Constraint, + unsigned Size) const { switch (Constraint[0]) { default: break; case 'y': @@ -3124,8 +3144,8 @@ public: if (RegNo == 1) return 2; return -1; } - bool validateInputSize(StringRef Constraint, - unsigned Size) const override { + bool validateOperandSize(StringRef Constraint, + unsigned Size) const override { switch (Constraint[0]) { default: break; case 'R': @@ -3142,7 +3162,7 @@ public: return Size <= 64; } - return X86TargetInfo::validateInputSize(Constraint, Size); + return X86TargetInfo::validateOperandSize(Constraint, Size); } }; } // end anonymous namespace diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 69cf6459d22..5aa1a2c86a9 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -121,6 +121,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, return StmtError(); OutputConstraintInfos.push_back(Info); + + const Type *Ty = OutputExpr->getType().getTypePtr(); + + // If this is a dependent type, just continue. We don't know the size of a + // dependent type. + if (Ty->isDependentType()) + continue; + + unsigned Size = Context.getTypeSize(Ty); + if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), + Size)) + return StmtError(Diag(OutputExpr->getLocStart(), + diag::err_asm_invalid_output_size) + << Info.getConstraintStr()); } SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; diff --git a/clang/test/CodeGen/mmx-inline-asm-error.c b/clang/test/CodeGen/mmx-inline-asm-error.c index 9be27fac585..1e2246176a1 100644 --- a/clang/test/CodeGen/mmx-inline-asm-error.c +++ b/clang/test/CodeGen/mmx-inline-asm-error.c @@ -5,8 +5,8 @@ vec256 foo(vec256 in) { vec256 out; asm("something %0" : : "y"(in)); // expected-error {{invalid input size for constraint 'y'}} - asm("something %0" : "=y"(out)); - asm("something %0, %0" : "+y"(out)); + asm("something %0" : "=y"(out)); // expected-error {{invalid output size for constraint '=y'}} + asm("something %0, %0" : "+y"(out)); // expected-error {{invalid output size for constraint '+y'}} return out; } diff --git a/clang/test/CodeGen/x86_32-inline-asm.c b/clang/test/CodeGen/x86_32-inline-asm.c index 65c7eeb5787..18fe4d0e14a 100644 --- a/clang/test/CodeGen/x86_32-inline-asm.c +++ b/clang/test/CodeGen/x86_32-inline-asm.c @@ -43,4 +43,17 @@ int func1() { __asm__ volatile("foo1 %0" : : "f" (val256)); // expected-error {{invalid input size for constraint 'f'}} __asm__ volatile("foo1 %0" : : "t" (val256)); // expected-error {{invalid input size for constraint 't'}} __asm__ volatile("foo1 %0" : : "u" (val256)); // expected-error {{invalid input size for constraint 'u'}} + + __asm__ volatile("foo1 %0" : "=R" (val)); // expected-error {{invalid output size for constraint '=R'}} + __asm__ volatile("foo1 %0" : "=q" (val)); // expected-error {{invalid output size for constraint '=q'}} + __asm__ volatile("foo1 %0" : "=Q" (val)); // expected-error {{invalid output size for constraint '=Q'}} + __asm__ volatile("foo1 %0" : "=a" (val)); // expected-error {{invalid output size for constraint '=a'}} + __asm__ volatile("foo1 %0" : "=b" (val)); // expected-error {{invalid output size for constraint '=b'}} + __asm__ volatile("foo1 %0" : "=c" (val)); // expected-error {{invalid output size for constraint '=c'}} + __asm__ volatile("foo1 %0" : "=d" (val)); // expected-error {{invalid output size for constraint '=d'}} + __asm__ volatile("foo1 %0" : "=S" (val)); // expected-error {{invalid output size for constraint '=S'}} + __asm__ volatile("foo1 %0" : "=D" (val)); // expected-error {{invalid output size for constraint '=D'}} + __asm__ volatile("foo1 %0" : "=A" (val128)); // expected-error {{invalid output size for constraint '=A'}} + __asm__ volatile("foo1 %0" : "=t" (val256)); // expected-error {{invalid output size for constraint '=t'}} + __asm__ volatile("foo1 %0" : "=u" (val256)); // expected-error {{invalid output size for constraint '=u'}} } |

