aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-08-08 06:24:23 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-08-08 15:36:51 +0200
commit7d3b07840e745152eca4723790c4a988b623107a (patch)
treeac9db7767a9f101aad7c8cb6d2d26e35928bffc2
parenta060d243f8dc17e399641b0dfebeb4faf5eb7580 (diff)
downloadsparse-7d3b07840e745152eca4723790c4a988b623107a.tar.gz
wstring: add support for examination of string initialization
The examination of a string initializer doesn't know about wide strings. The only thing needed is if the base type is some kind of char but for wide chars, this type is the same as 'int' and an array of ints can't be treated the same as an array of chars. So, do the detection for wide string initializers as: 1) check that the LHS base type is wchar_ctype 2) check that the RHS is a kind of string expression (possibly between braces or parenthesis, recursively). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--symbol.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/symbol.c b/symbol.c
index 6fcb1b15..7f0c8558 100644
--- a/symbol.c
+++ b/symbol.c
@@ -307,6 +307,29 @@ void merge_type(struct symbol *sym, struct symbol *base_type)
merge_type(sym, sym->ctype.base_type);
}
+static bool is_wstring_expr(struct expression *expr)
+{
+ while (expr) {
+ switch (expr->type) {
+ case EXPR_STRING:
+ return 1;
+ case EXPR_INITIALIZER:
+ if (expression_list_size(expr->expr_list) != 1)
+ return 0;
+ expr = first_expression(expr->expr_list);
+ break;
+ case EXPR_PREOP:
+ if (expr->op == '(') {
+ expr = expr->unop;
+ break;
+ }
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
static int count_array_initializer(struct symbol *t, struct expression *expr)
{
int nr = 0;
@@ -321,6 +344,8 @@ static int count_array_initializer(struct symbol *t, struct expression *expr)
*/
if (t->ctype.base_type == &int_type && t->rank == -2)
is_char = 1;
+ else if (t == wchar_ctype && is_wstring_expr(expr))
+ is_char = 1;
switch (expr->type) {
case EXPR_INITIALIZER: {