[v3,3/4] c: runtime checking for assigment of VM types
Checks
Commit Message
Support instrumentation of functions called via pointers. To do so,
record the declaration with the parameter types, so that it can be
retrieved later.
gcc/c:
c-decl.cc (get_parm_info): Record function declaration
for arguments.
c-typeck.cc (process_vm_constraints): Instrument functions
called via pointers.
gcc/testsuide/gcc.dg:
* vla-bounds-func-1.c: Add warning.
* vla-bounds-fnptr-1.c: New test.
* vla-bounds-fnptr-2.c: New test.
* vla-bounds-fnptr-3.c: New test.
---
gcc/c/c-decl.cc | 4 ++++
gcc/c/c-typeck.cc | 14 ++++++++++--
gcc/testsuite/gcc.dg/vla-bounds-fnptr-1.c | 24 ++++++++++++++++++++
gcc/testsuite/gcc.dg/vla-bounds-fnptr-2.c | 27 +++++++++++++++++++++++
gcc/testsuite/gcc.dg/vla-bounds-fnptr-3.c | 25 +++++++++++++++++++++
gcc/testsuite/gcc.dg/vla-bounds-func-1.c | 2 +-
6 files changed, 93 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/vla-bounds-fnptr-1.c
create mode 100644 gcc/testsuite/gcc.dg/vla-bounds-fnptr-2.c
create mode 100644 gcc/testsuite/gcc.dg/vla-bounds-fnptr-3.c
@@ -8628,6 +8628,10 @@ get_parm_info (bool ellipsis, tree expr)
declared types. The back end may override this later. */
DECL_ARG_TYPE (decl) = type;
types = tree_cons (0, type, types);
+
+ /* Record the decl for use for VLA bounds checking. */
+ if (flag_vla_bounds)
+ TREE_PURPOSE (types) = decl;
}
break;
@@ -3958,9 +3958,19 @@ process_vm_constraints (location_t location,
}
else
{
- /* Functions called via pointers are not yet supported. */
- return void_node;
+ while (TREE_CODE (function) != FUNCTION_TYPE)
+ function = TREE_TYPE (function);
+
+ args = TREE_PURPOSE (TYPE_ARG_TYPES (function));
+
+ if (!args)
+ {
+ /* FIXME: this can happen when forming composite types for the
+ conditional operator. */
+ return void_node;
+ }
}
+ gcc_assert (TREE_CODE (args) == PARM_DECL);
}
for (struct instrument_data* d = *instr_vec; d; d = d->next)
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-fvla-bounds" } */
+
+#include <signal.h>
+#include <stdlib.h>
+
+static void handler(int) { exit(0); }
+
+void foo1(void (*p)(int n, char (*a)[n]))
+{
+ char A0[3];
+ (*p)(3, &A0);
+ (*p)(4, &A0); // 4 != 3
+ abort();
+}
+
+void b0(int n, char (*a)[n]) { }
+
+int main()
+{
+ signal(SIGILL, handler);
+
+ foo1(&b0);
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-fvla-bounds" } */
+
+#include <signal.h>
+#include <stdlib.h>
+
+static void handler(int) { exit(0); }
+
+int n;
+
+void foo2(void (*p)(int n, char (*a)[n]))
+{
+ n = 4;
+ char A0[3];
+ (*p)(3, &A0);
+ (*p)(4, &A0);
+ abort();
+}
+
+void b1(int n0, char (*a)[n]) { }
+
+int main()
+{
+ signal(SIGILL, handler);
+
+ foo2(&b1); // we should diagnose mismatch
+}
new file mode 100644
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-fvla-bounds" } */
+
+#include <signal.h>
+#include <stdlib.h>
+
+static void handler(int) { exit(0); }
+
+int n;
+
+void foo3(void (*p)(int n0, char (*a)[n]))
+{
+ n = 4;
+ char A0[3];
+ (*p)(3, &A0); // 4 != 3
+ abort();
+}
+
+void b1(int n0, char (*a)[n]) { }
+
+int main()
+{
+ signal(SIGILL, handler);
+ foo3(&b1);
+}
@@ -30,7 +30,7 @@ void f(void)
int u = 3; int v = 4;
char a[u][v];
- (1 ? f1 : f2)(u, v, a);
+ (1 ? f1 : f2)(u, v, a); /* "Function call not instrumented." */
}
/* size expression in parameter */
--
2.39.2