diff options
| author | Dan Carpenter <dan.carpenter@linaro.org> | 2025-10-15 16:08:13 +0300 |
|---|---|---|
| committer | Chris Li <sparse@chrisli.org> | 2025-10-16 21:52:33 -0700 |
| commit | fbdde3127b83e6d09e0ba808d7925dd84407f3c6 (patch) | |
| tree | 602d0e365e38d1ed99ad775784728b9135b9c68c | |
| parent | dc9efe442b8949234a6599fdc94dc7221dd040e1 (diff) | |
| download | sparse-dev-master.tar.gz | |
People are adding compile time asserts to check whether strings are
the expected length. In GCC and Clang strlen("foo") is expanded at
compile time so this works, but in Sparse it triggers a "bad constant
expression" warning. Implement expand_strlen() to handle string
literals.
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/all/CANiDSCsBAq3Yx4ybarUb_1NkQ-bvfXvWqb-DfqXatkiYJFZWiQ@mail.gmail.com/
Signed-off-by: Chris Li <sparse@chrisli.org>
| -rw-r--r-- | builtin.c | 25 |
1 files changed, 24 insertions, 1 deletions
@@ -29,6 +29,7 @@ #include "expand.h" #include "symbol.h" #include "compat/bswap.h" +#include "string.h" #include <stdarg.h> #define dyntype incomplete_ctype @@ -596,6 +597,28 @@ static struct symbol_op object_size_op = { .expand = expand_object_size, }; +static int expand_strlen(struct expression *expr, int cost) +{ + struct expression *arg = first_expression(expr->args); + + if (!arg) + return UNSAFE; + if (arg->type == EXPR_SYMBOL) + arg = arg->symbol->initializer; + if (!arg || arg->type != EXPR_STRING || !arg->string->length) + return UNSAFE; + + expr->flags |= CEF_SET_ICE; + expr->type = EXPR_VALUE; + expr->value = strlen(arg->string->data); + expr->taint = 0; + return 0; +} + +static struct symbol_op strlen_op = { + .expand = expand_strlen, +}; + /* * Builtin functions */ @@ -775,7 +798,7 @@ static const struct builtin_fn builtins_common[] = { { "__builtin_strcpy", &string_ctype, 0, { &string_ctype, &const_string_ctype }}, { "__builtin_strcspn", size_t_ctype, 0, { &const_string_ctype, &const_string_ctype }}, { "__builtin_strdup", &string_ctype, 0, { &const_string_ctype }}, - { "__builtin_strlen", size_t_ctype, 0, { &const_string_ctype }}, + { "__builtin_strlen", size_t_ctype, 0, { &const_string_ctype }, .op = &strlen_op}, { "__builtin_strncasecmp", &int_ctype, 0, { &const_string_ctype, &const_string_ctype, size_t_ctype }}, { "__builtin_strncat", &string_ctype, 0, { &string_ctype, &const_string_ctype, size_t_ctype }}, { "__builtin_strncmp", &int_ctype, 0, { &const_string_ctype, &const_string_ctype, size_t_ctype }}, |
