aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-plugin/printf_check.cc214
1 files changed, 53 insertions, 161 deletions
diff --git a/clang-plugin/printf_check.cc b/clang-plugin/printf_check.cc
index a6918e425..5ebbeef1f 100644
--- a/clang-plugin/printf_check.cc
+++ b/clang-plugin/printf_check.cc
@@ -370,63 +370,34 @@ namespace rspamd {
}
static bool
- int_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
- {
- auto type = arg->getType ().split ().Ty;
-
- auto desugared_type = type->getUnqualifiedDesugaredType ();
-
- if (!desugared_type->isIntegerType ()) {
- print_error (std::string ("bad integer argument for %d or * arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
- print_error (std::string ("bad integer argument for %d or * arg: ") +
- arg->getType ().getAsString(), arg, ctx->past);
- return false;
- }
-
- auto builtin_type = dyn_cast<BuiltinType>(desugared_type);
- auto kind = builtin_type->getKind ();
-
- if (kind != BuiltinType::Kind::UInt &&
- kind != BuiltinType::Kind::Int) {
- print_error (std::string ("bad integer argument for %d or * arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- return true;
- }
-
- static bool
- long_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+ check_builtin_type (const Expr *arg, struct PrintfArgChecker *ctx,
+ const std::vector<BuiltinType::Kind> &k, const std::string &fmt)
{
auto type = arg->getType ().split ().Ty;
auto desugared_type = type->getUnqualifiedDesugaredType ();
- if (!desugared_type->isIntegerType ()) {
- print_error (
- std::string ("bad integer argument for %l arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
+ if (!desugared_type->isBuiltinType ()) {
print_error (
- std::string ("bad integer argument for %l arg: ") +
+ std::string ("not a builtin type for ") + fmt + " arg: " +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();
+ auto found = false;
+
+ for (auto kk : k) {
+ if (kind == kk) {
+ found = true;
+ break;
+ }
+ }
- if (kind != BuiltinType::Kind::ULong &&
- kind != BuiltinType::Kind::Long) {
+ if (!found) {
print_error (
- std::string ("bad integer argument for %l arg: ") +
+ std::string ("bad argument for ") + fmt + " arg: " +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
@@ -435,79 +406,48 @@ namespace rspamd {
}
static bool
- char_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+ int_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
- auto type = arg->getType ().split ().Ty;
-
- auto desugared_type = type->getUnqualifiedDesugaredType ();
-
- if (!desugared_type->isCharType ()) {
- print_error (
- std::string ("bad char argument for %c arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
- print_error (
- std::string ("bad char argument for %c arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
- auto kind = builtin_type->getKind ();
+ return check_builtin_type (arg, ctx, {BuiltinType::Kind::UInt,
+ BuiltinType::Kind::Int}, "%d or *");
+ }
- if (kind != BuiltinType::Kind::UChar &&
- kind != BuiltinType::Kind::SChar) {
- print_error (
- std::string ("bad char argument for %c arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
+ static bool
+ long_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+ {
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::ULong,
+ BuiltinType::Kind::Long},
+ "%l");
+ }
- return true;
+ static bool
+ char_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+ {
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::UChar,
+ BuiltinType::Kind::SChar},
+ "%c");
}
static bool
size_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
- auto type = arg->getType ().split ().Ty;
-
- auto desugared_type = type->getUnqualifiedDesugaredType ();
-
- if (!desugared_type->isIntegerType ()) {
- print_error (
- std::string ("bad integer argument for %z arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
- print_error (
- std::string ("bad integer argument for %z arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
- auto kind = builtin_type->getKind ();
-
if (sizeof (size_t) == sizeof (long)) {
- if (kind != BuiltinType::Kind::ULong &&
- kind != BuiltinType::Kind::Long) {
- print_error (
- std::string ("bad integer argument for %z arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::ULong,
+ BuiltinType::Kind::Long},
+ "%z");
}
else if (sizeof (size_t) == sizeof (int)) {
- if (kind != BuiltinType::Kind::UInt &&
- kind != BuiltinType::Kind::Int) {
- print_error (
- std::string ("bad integer argument for %z arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::UInt,
+ BuiltinType::Kind::Int},
+ "%z");
}
return true;
@@ -516,66 +456,18 @@ namespace rspamd {
static bool
double_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
- auto type = arg->getType ().split ().Ty;
-
- auto desugared_type = type->getUnqualifiedDesugaredType ();
-
- if (!desugared_type->isRealFloatingType ()) {
- print_error (
- std::string ("bad double argument for %f or %g arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
- print_error (
- std::string ("bad double argument for %f or %g arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
- auto kind = builtin_type->getKind ();
-
- if (kind != BuiltinType::Kind::Double) {
- print_error (
- std::string ("bad double argument for %f or %g arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- return true;
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::Double},
+ "%f or %g");
}
static bool
long_double_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
- auto type = arg->getType ().split ().Ty;
-
- auto desugared_type = type->getUnqualifiedDesugaredType ();
-
- if (!desugared_type->isRealFloatingType ()) {
- print_error (
- std::string ("bad long double argument for %F or %G arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
- else if (!desugared_type->isBuiltinType ()) {
- print_error (
- std::string ("bad long double argument for %F or %G arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
- auto kind = builtin_type->getKind ();
-
- if (kind != BuiltinType::Kind::LongDouble) {
- print_error (
- std::string ("bad long double argument for %F or %G arg: ") +
- arg->getType ().getAsString (), arg, ctx->past);
- return false;
- }
-
- return true;
+ return check_builtin_type (arg,
+ ctx,
+ {BuiltinType::Kind::LongDouble},
+ "%F or %G");
}
};