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 | |
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
-rw-r--r-- | include/clang/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 34 | ||||
-rw-r--r-- | test/CodeGen/builtins-mips-args.c | 4 |
3 files changed, 39 insertions, 0 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 5379821782..c1d0d63819 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -7061,6 +7061,7 @@ private: ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); 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 diff --git a/test/CodeGen/builtins-mips-args.c b/test/CodeGen/builtins-mips-args.c index 7dc73776a7..4bc6f248c1 100644 --- a/test/CodeGen/builtins-mips-args.c +++ b/test/CodeGen/builtins-mips-args.c @@ -6,4 +6,8 @@ void foo() { int a = 3; __builtin_mips_wrdsp(2052, a); // expected-error{{argument to '__builtin_mips_wrdsp' must be a constant integer}} __builtin_mips_rddsp(a); // expected-error{{argument to '__builtin_mips_rddsp' must be a constant integer}} + __builtin_mips_wrdsp(2052, -1); // expected-error{{argument should be a value from 0 to 63}} + __builtin_mips_rddsp(-1); // expected-error{{argument should be a value from 0 to 63}} + __builtin_mips_wrdsp(2052, 64); // expected-error{{argument should be a value from 0 to 63}} + __builtin_mips_rddsp(64); // expected-error{{argument should be a value from 0 to 63}} } |