diff options
| author | Akira Hatanaka <ahatanaka@apple.com> | 2014-09-18 18:17:18 +0000 |
|---|---|---|
| committer | Akira Hatanaka <ahatanaka@apple.com> | 2014-09-18 18:17:18 +0000 |
| commit | 974131ea8825041673a8c8dda7c42f9a9376eb17 (patch) | |
| tree | 39e922e630d9141febda031d35e6786f196b4729 /clang/lib | |
| parent | 3e6a0be4c4531d97134daea5bd32c5564e3d34f5 (diff) | |
| download | bcm5719-llvm-974131ea8825041673a8c8dda7c42f9a9376eb17.tar.gz bcm5719-llvm-974131ea8825041673a8c8dda7c42f9a9376eb17.zip | |
[X86, inlineasm] Check that the output size is correct for the given constraint.
llvm-svn: 218064
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 14 |
2 files changed, 37 insertions, 3 deletions
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; |

