@@ -1772,6 +1772,7 @@ static struct symbol *degenerate(struct expression *expr)
*expr = *expr->unop;
ctype = create_pointer(expr, ctype, 1);
expr->ctype = ctype;
+ mark_addressable(expr);
default:
/* nothing */;
}
@@ -11,7 +11,6 @@ static int bar(void)
/*
* check-name: eval/addressable-degen
* check-command: test-linearize -fdump-ir $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-contains: load\\.
new file mode 100644
@@ -0,0 +1,15 @@
+int test_array(int i)
+{
+ static const int a[3] = { 1, 2, 3, };
+
+ return a[1];
+}
+
+/*
+ * check-name: constant-init-array
+ * check-command: test-linearize -Wno-decl -fdump-ir $file
+ *
+ * check-output-ignore
+ * check-output-excludes: phisrc\\..*return.*\\$2
+ * check-output-contains: load\\.
+ */
Symbols which have their address taken (with the 'addressof' operator: &) are marked as such (with the modifier MOD_ADDRESSABLE). But degenerated arrays and functions have their address implicitly taken. MOD_ADDRESSABLE is used to prevent to replace a symbol dereference nto the value used to initialize to it. For example, in code like: static int foo(void) { int x[2] = { 1, 2 }; return x[1]; } the return expression can be replaced by 2. This is not the case case if the array is first passed in a function call, like here: extern void def(void *, unsigned int); static int bar(void) { int x[2] = { 1, 2 }; def(x, sizeof(x)); return x[1]; } Fix this by marking degenerated arrays (and functions) as also being addressable. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- evaluate.c | 1 + validation/eval/addressable-degen.c | 1 - validation/expand/constant-init-array.c | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 validation/expand/constant-init-array.c