diff options
author | Simon Atanasyan <satanasyan@mips.com> | 2012-07-08 09:30:00 +0000 |
---|---|---|
committer | Simon Atanasyan <satanasyan@mips.com> | 2012-07-08 09:30:00 +0000 |
commit | fad0a32da8ea34a58aa0a0dd3fd67cd30959b080 (patch) | |
tree | 4e4a96fa5e280fc07f4e7b8230b185103e038248 /lib/Sema/SemaChecking.cpp | |
parent | e471d87a278cf2fba653b2f6d2c8d9c33f5721b7 (diff) |
MIPS: Range check __builtin_mips_wrdsp / __builtin_mips_rddsp arguments against the upper/lower values.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159911 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 708fd14e49..91f5ce5813 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -287,6 +287,13 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) return ExprError(); break; + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + if (CheckMipsBuiltinFunctionCall(BuiltinID, TheCall)) + return ExprError(); + break; default: break; } @@ -424,6 +431,33 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return false; } +bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { + unsigned i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: return false; + case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; + case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; + }; + + // We can't check the value of a dependent argument. + if (TheCall->getArg(i)->isTypeDependent() || + TheCall->getArg(i)->isValueDependent()) + return false; + + // Check that the immediate argument is actually a constant. + llvm::APSInt Result; + if (SemaBuiltinConstantArg(TheCall, i, Result)) + return true; + + // Range check against the upper/lower values for this instruction. + unsigned Val = Result.getZExtValue(); + if (Val < l || Val > u) + return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) + << l << u << TheCall->getArg(i)->getSourceRange(); + + return false; +} + /// Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo /// parameter with the FormatAttr's correct format_idx and firstDataArg. /// Returns true when the format fits the function and the FormatStringInfo has |