From 0e7c46401bd3a3094459d8ea5231906caaf862a8 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Thu, 7 Dec 2017 13:31:38 +0100 Subject: [PATCH] Fix this test to work properly with accurate CmpEQ/NE definedness tracking Memcheck reports an error on "if (n == 42)" in this test. Unless, that is, accurate CmpEQ/NE definedness tracking is enabled. If you stare at this long enough it is possible to see that the test "n == 42" isn't actually undefined, because |n| is only ever zero or one, and only its least significant bit is undefined. So the equality comparison against 42 is defined because there are corresponding bits in the two operands that are different and are both defined. This commit fixes that by comparing with 1, which forces the result to really depend on the only undefined bit in |n|. I also added robustification: * return arbitrary values from gcc_cant_inline_me(), so as to avoid gcc simply copying the input to the output or otherwise deleting the conditional branch. * marking gcc_cant_inline_me() as un-inlineable * Putting compiler barriers in the second conditional in main(), so gcc can't simply ignore the result of the call to gcc_cant_inline_me() and then delete the call entirely. --- memcheck/tests/manuel3.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/memcheck/tests/manuel3.c b/memcheck/tests/manuel3.c index 91030fc65..8e600777a 100644 --- a/memcheck/tests/manuel3.c +++ b/memcheck/tests/manuel3.c @@ -1,8 +1,8 @@ #include #include - -int gcc_cant_inline_me ( int ); - +int foo, bar; +#define CBAR do { __asm__ __volatile__("":::"cc","memory"); } while (0) +int* gcc_cant_inline_me ( int ); int main () { int *x, y; @@ -11,18 +11,18 @@ int main () y = *x == 173; - if (gcc_cant_inline_me(y)) { } + if (gcc_cant_inline_me(y) == &foo) { CBAR; } else { CBAR; } return 0; } /* must be AFTER main */ -int gcc_cant_inline_me ( int n ) +__attribute__((noinline)) int* gcc_cant_inline_me ( int n ) { - if (n == 42) - return 1; /* forty-two, dudes! */ + if (n == 1) + return &foo; /* foo! */ else - return 0; /* some other number, dudes! */ + return &bar; /* bar! */ }