aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-16 21:13:54 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-16 21:13:54 +0100
commit4d15929201e0bf91df213e624d833541b61c4cb8 (patch)
tree6de666ef6f265170ee4318d3e5d47f17487672b1 /validation
parent8376a70ce36ef3e22bfbab06455f5b6397f9c2de (diff)
downloadsparse-dev-4d15929201e0bf91df213e624d833541b61c4cb8.tar.gz
give a type to all function arguments
The linearized code, sparse's IR, have no use of C's complex type system. Those types are checked in previous phases and the pseudos doesn't have a type directly attached to them as all the needed typing info info are conveyed by the instructions. In particular, PSEUDO_VAL (used for integer and address constants) are completely typeless. There is a problem with this when calling a variadic function with a constant argument as in this case there is no type in the function prototype (for the variadic part, of course) and there is no defining instructions holding the type of the argument. Possible but rejected solutions are: * give a full type to all pseudos This is silly as, for example 'int 0' and 'unsigned int 0' are, really, the same constants. * give simply a size to all pseudos This seems to be simple enough but *currently* it negatively impacts CSE (maybe because of some others deficiencies in the type system, especially for casts). * give a type to all function arguments via a new instruction that would mimic argument passing (OP_ARG or OP_PUSH). This solution is interesting, especially as it gives a placeholder for real argument passing at code generation time, but: 0) they can be added, if needed, when some code generation will be done. 1) it creates a superfluous instruction for every argument of every function call 2) these instructions are essentially copy instructions in disguise. So, since the problem only exist for constants used in variadic arguments (and currently, it's only a problem for sparse-llvm), the solution selected is to add to OP_CALLs a list holding the type of all arguments. More exactly, it reuses the field .fntype which was used to store the type of the function, and changes it to a list holding the function type *and* the type of all effective arguments. Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation')
-rw-r--r--validation/call-variadic.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/validation/call-variadic.c b/validation/call-variadic.c
new file mode 100644
index 00000000..a438b43a
--- /dev/null
+++ b/validation/call-variadic.c
@@ -0,0 +1,23 @@
+#define NULL ((void*)0)
+
+extern int print(const char *msg, ...);
+
+int foo(const char *fmt, int a, long l, int *p)
+{
+ print("msg %c: %d %d/%ld %ld/%p %p\n", 'x', a, __LINE__, l, 0L, p, NULL);
+}
+
+/*
+ * check-name: call-variadic
+ * check-command: test-linearize -Wno-decl -m64 $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ call.32 %r5 <- print, "msg %c: %d %d/%ld %ld/%p %p\n", $120, %arg2, $7, %arg3, $0, %arg4, $0
+ ret.32 %r5
+
+
+ * check-output-end
+ */