aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--evaluate.c1
-rw-r--r--validation/linear/deref-ptr-ptr.c26
-rw-r--r--validation/linear/unexamined-base-type.c36
3 files changed, 63 insertions, 0 deletions
diff --git a/evaluate.c b/evaluate.c
index 840f98d3..4be4e8e5 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1777,6 +1777,7 @@ static struct symbol *evaluate_dereference(struct expression *expr)
ctype = ctype->ctype.base_type;
target = ctype->ctype.base_type;
+ examine_symbol_type(target);
switch (ctype->type) {
default:
diff --git a/validation/linear/deref-ptr-ptr.c b/validation/linear/deref-ptr-ptr.c
new file mode 100644
index 00000000..963acd36
--- /dev/null
+++ b/validation/linear/deref-ptr-ptr.c
@@ -0,0 +1,26 @@
+char *foo(char **pfmt)
+{
+ return ++*pfmt;
+}
+
+/*
+ * check-name: deref-ptr-ptr
+ * check-command: test-linearize -m64 -Wno-decl $file
+ *
+ * check-output-excludes: load[^.]
+ * check-output-contains: load\.
+ * check-output-excludes: store[^.]
+ * check-output-contains: store\.
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ load.64 %r2 <- 0[%arg1]
+ add.64 %r3 <- %r2, $1
+ store.64 %r3 -> 0[%arg1]
+ ret.64 %r3
+
+
+ * check-output-end
+ */
diff --git a/validation/linear/unexamined-base-type.c b/validation/linear/unexamined-base-type.c
new file mode 100644
index 00000000..96aee3f0
--- /dev/null
+++ b/validation/linear/unexamined-base-type.c
@@ -0,0 +1,36 @@
+# define __force __attribute__((force))
+
+struct s {
+ int a;
+};
+
+static int foo(struct s *s)
+{
+ return (*((typeof(s->a) __force *) &s->a)) & 1;
+}
+
+static void bar(struct s *d, struct s *s1, struct s *s2)
+{
+ *d = *s1, *d = *s2;
+}
+
+/*
+ * check-name: unexamined base type
+ * check-command: test-linearize -Wno-decl $file
+ * check-description:
+ * Test case for missing examine in evaluate_dereference()'s
+ * target base type. In this case, the loaded value has a
+ * a null size, giving the wrongly generated code for foo():
+ * ptrcast.64 %r3 <- (64) %arg1
+ * load %r4 <- 0[%r3]
+ * ^^^ !! WRONG !!
+ * cast.32 %r5 <- (0) %r4
+ * ^^^ !! WRONG !!
+ * and.32 %r6 <- %r5, $1
+ * ret.32 %r6
+ *
+ * check-output-ignore
+ * check-output-excludes: load[^.]
+ * check-output-excludes: cast\..*(0)
+ * check-output-excludes: store[^.]
+ */