diff mbox series

[17/17] constant expansion of strings

Message ID 20191210225921.94897-18-luc.vanoostenryck@gmail.com (mailing list archive)
State Deferred, archived
Headers show
Series improve expansion of constant symbols | expand

Commit Message

Luc Van Oostenryck Dec. 10, 2019, 10:59 p.m. UTC
EXPR_STRING can be considered as a kind of specialized
initializer for strings. Using EXPR_INITIALIZER for them
would be much more costly.

However, unlike EXPR_INITIALIZER, EXPR_STRING are not used
by constant_symbol_value() to expand dereferences of symbols
with constant value.

Change this by adding to constant_symbol_value() the code
needed to expand dereferences of strings. Two situations
need to be handled: one for string literals and another
for declared strings.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 expand.c                                 | 30 ++++++++++++++++++++++++
 validation/expand/constant-init-string.c |  1 -
 2 files changed, 30 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/expand.c b/expand.c
index 1885a4eaad2a..eeddb633c9bf 100644
--- a/expand.c
+++ b/expand.c
@@ -681,6 +681,27 @@  redo:
 	return &value;
 }
 
+static struct expression *constant_string_value(struct expression *e, int offset)
+{
+	static struct expression value;
+	struct string *string;
+	struct symbol *ctype;
+
+	if (e->wide)
+		return NULL;
+	string = e->string;
+	if (offset >= string->length)
+		return NULL;
+	ctype = e->ctype;
+	if (!ctype)
+		return NULL;
+
+	value.type = EXPR_VALUE;
+	value.value = string->data[offset];
+	value.ctype = get_base_type(ctype->ctype.base_type);
+	return &value;
+}
+
 /*
  * Look up a trustable initializer value at the requested offset.
  *
@@ -714,6 +735,15 @@  static struct expression *constant_symbol_value(struct symbol *sym, int offset)
 		} END_FOR_EACH_PTR(entry);
 
 		value = default_initializer(sym, offset);
+	} else if (value->type == EXPR_STRING) {
+		value = constant_string_value(value, offset);
+	} else if (value->type == EXPR_PREOP && value->op == '*') {
+		if (value->unop->type == EXPR_SYMBOL) {
+			struct symbol *sym = value->unop->symbol;
+			struct expression *init = sym->initializer;
+			if (init && init->type == EXPR_STRING)
+				value = constant_string_value(init, offset);
+		}
 	}
 	return value;
 }
diff --git a/validation/expand/constant-init-string.c b/validation/expand/constant-init-string.c
index 42ae9bd3d8a4..033882a0bed9 100644
--- a/validation/expand/constant-init-string.c
+++ b/validation/expand/constant-init-string.c
@@ -7,7 +7,6 @@  char foo(void)
 /*
  * check-name: constant-init-nested-array
  * check-command: test-linearize -Wno-decl -fdump-ir $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: phisrc\\..*\\$63