summaryrefslogtreecommitdiff
path: root/tests/tests2/82_attribs_position.c
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2020-08-14 23:04:13 +0100
committerThomas Preud'homme <robotux@celest.fr>2020-08-14 23:04:13 +0100
commitafd09586d7ead4f146ad7a7a471be34196b3c6bc (patch)
tree87854be29fb4264b979b700fa45445f58faa4c26 /tests/tests2/82_attribs_position.c
parente2ccf3981d78dfeb390d22c74625b60310100abb (diff)
New upstream version 0.9.27+git20200814.62c30a4a
Diffstat (limited to 'tests/tests2/82_attribs_position.c')
-rw-r--r--tests/tests2/82_attribs_position.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c
index 7c9f987..fd3f2c4 100644
--- a/tests/tests2/82_attribs_position.c
+++ b/tests/tests2/82_attribs_position.c
@@ -16,4 +16,50 @@ void __attribute__((stdcall)) foo (void)
{
}
-int main () { return 0; }
+#define __stdcall __attribute__((stdcall))
+extern int some_stdcall_func (int, int, int) __stdcall;
+__stdcall int __stdcall some_stdcall_func(int foo, int bar, int baz) {
+ //printf("Hello from stdcall: %i %i %i\n", foo, bar, baz);
+ return 43;
+}
+
+/* The actual attribute isn't important, must just be
+ parsable. */
+#define ATTR __attribute__((__noinline__))
+int ATTR actual_function() {
+ return 42;
+}
+
+extern int printf (const char *, ...);
+static int globalvar;
+int main()
+{
+ void *function_pointer = &actual_function;
+ int localvar = 42, i;
+
+ int a = ((ATTR int(*) (void)) function_pointer)();
+ printf("%i\n", a);
+
+ /* In the following we once misparsed 'ATTR *' is a btype
+ and hence the whole type was garbled. */
+ int b = ( (int(ATTR *)(void)) function_pointer)();
+ printf("%i\n", b);
+
+ /* All these should work and leave the stack pointer in its original
+ position. */
+ some_stdcall_func(1, 10, 100);
+ ((int __stdcall (*)(int, int, int))some_stdcall_func) (2, 20, 200);
+ ((int(*__stdcall)(int, int, int))some_stdcall_func) (3, 30, 300);
+ for (i = 0; i < 1024; i++) {
+ globalvar = i;
+ /* This was once misparsed at <= gitrev 325241c0, forgetting
+ the stdcall attribute on the function pointer leading to
+ stack increment being done twice (in callee and caller).
+ This will clobber 'i' and 'localvar' which is how we detect
+ this. */
+ ((int(__stdcall*)(int, int, int))some_stdcall_func) (4, 40, 400);
+ if (localvar != 42 || globalvar != i)
+ printf("error, localvar=%d i=%d globalvar=%d\n", localvar, i, globalvar);
+ }
+ return 0;
+}