]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix this test to work properly with accurate CmpEQ/NE definedness tracking
authorJulian Seward <jseward@acm.org>
Thu, 7 Dec 2017 12:31:38 +0000 (13:31 +0100)
committerJulian Seward <jseward@acm.org>
Thu, 7 Dec 2017 12:31:38 +0000 (13:31 +0100)
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

index 91030fc65d68ac45ef8b6aa372e49d302af59d5c..8e600777a8495a8e089b9c938f44cba5acb397e3 100644 (file)
@@ -1,8 +1,8 @@
 #include <stdio.h>
 #include <stdlib.h>
-
-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! */
 }