msan_test.cc revision 0f92deb81207c80481ff0257fbaba640fe669633
10231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//===-- msan_test.cc ------------------------------------------------------===//
20231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//
30231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//                     The LLVM Compiler Infrastructure
40231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//
50231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// This file is distributed under the University of Illinois Open Source
60231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// License. See LICENSE.TXT for details.
70231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//
80231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//===----------------------------------------------------------------------===//
90231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//
100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// This file is a part of MemorySanitizer.
110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//
120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// MemorySanitizer unit tests.
130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov//===----------------------------------------------------------------------===//
140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include "sanitizer/msan_interface.h"
160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include "msandr_test_so.h"
170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include "gtest/gtest.h"
180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <stdlib.h>
200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <stdarg.h>
210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <stdio.h>
220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <assert.h>
230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <wchar.h>
240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
25e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov#include <dlfcn.h>
260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <unistd.h>
270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <limits.h>
280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/time.h>
290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/types.h>
300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/stat.h>
310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <fcntl.h>
320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/resource.h>
330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/ioctl.h>
340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/utsname.h>
350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/mman.h>
360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#include <sys/vfs.h>
370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#if defined(__i386__) || defined(__x86_64__)
390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov# include <emmintrin.h>
400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov# define MSAN_HAS_M128 1
410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#else
420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov# define MSAN_HAS_M128 0
430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#endif
440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef unsigned char      U1;
460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef unsigned short     U2;  // NOLINT
470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef unsigned int       U4;
480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef unsigned long long U8;  // NOLINT
490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef   signed char      S1;
500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef   signed short     S2;  // NOLINT
510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef   signed int       S4;
520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtypedef   signed long long S8;  // NOLINT
530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#define NOINLINE      __attribute__((noinline))
540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#define INLINE      __attribute__((always_inline))
550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovstatic bool TrackingOrigins() {
5711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  S8 x;
5811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  __msan_set_origin(&x, sizeof(x), 0x1234);
59250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __msan_get_origin(&x);
6011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  __msan_set_origin(&x, sizeof(x), 0);
6111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  return origin == 0x1234;
6211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov}
630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_UMR(action) \
650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    do {                        \
660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(1); \
670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      action;                   \
680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(0); \
690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    } while (0)
700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_UMR_O(action, origin) \
720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    do {                                            \
730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(1);                     \
740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      action;                                       \
750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(0);                     \
760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      if (TrackingOrigins())                        \
7712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov        EXPECT_EQ(origin, __msan_get_umr_origin()); \
780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    } while (0)
790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_UMR_S(action, stack_origin) \
810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    do {                                            \
820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(1);                     \
830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      action;                                       \
840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      __msan_set_expect_umr(0);                     \
85250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov      U4 id = __msan_get_umr_origin();             \
860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      const char *str = __msan_get_origin_descr_if_stack(id); \
870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      if (!str || strcmp(str, stack_origin)) {      \
880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov        fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov                id, stack_origin, str);  \
900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov        EXPECT_EQ(1, 0);                            \
910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      }                                             \
920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    } while (0)
930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_POISONED(x) ExpectPoisoned(x)
9511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
9611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovtemplate<typename T>
9711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovvoid ExpectPoisoned(const T& t) {
9811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
9911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov}
10011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
10111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_POISONED_O(x, origin) \
10211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  ExpectPoisonedWithOrigin(x, origin)
10311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
10411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovtemplate<typename T>
10511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovvoid ExpectPoisonedWithOrigin(const T& t, unsigned origin) {
10611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
10711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  if (TrackingOrigins())
10811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_EQ(origin, __msan_get_origin((void*)&t));
10911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov}
11011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
11111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_POISONED_S(x, stack_origin) \
11211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  ExpectPoisonedWithStackOrigin(x, stack_origin)
11311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
11411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovtemplate<typename T>
11511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovvoid ExpectPoisonedWithStackOrigin(const T& t, const char *stack_origin) {
11611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
117250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 id = __msan_get_origin((void*)&t);
11811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  const char *str = __msan_get_origin_descr_if_stack(id);
11911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  if (!str || strcmp(str, stack_origin)) {
12011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s",
12111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov        id, stack_origin, str);
12211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_EQ(1, 0);
12311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  }
12411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov}
12511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
12611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov#define EXPECT_NOT_POISONED(x) ExpectNotPoisoned(x)
12711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
12811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovtemplate<typename T>
12911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovvoid ExpectNotPoisoned(const T& t) {
13011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_EQ(-1, __msan_test_shadow((void*)&t, sizeof(t)));
13111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov}
1320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic U8 poisoned_array[100];
1340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
1350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovT *GetPoisoned(int i = 0, T val = 0) {
1360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *res = (T*)&poisoned_array[i];
1370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *res = val;
1380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&poisoned_array[i], sizeof(T));
1390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
1400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
1410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
143250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovT *GetPoisonedO(int i, U4 origin, T val = 0) {
1440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *res = (T*)&poisoned_array[i];
1450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *res = val;
1460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&poisoned_array[i], sizeof(T));
1470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(&poisoned_array[i], sizeof(T), origin);
1480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
1490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
1500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// This function returns its parameter but in such a way that compiler
1520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// can not prove it.
1530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
1540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE
1550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic T Ident(T t) {
1560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  volatile T ret = t;
1570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return ret;
1580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
1590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
1610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic volatile int g_one = 1;
1630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic volatile int g_zero = 0;
1640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic volatile int g_0 = 0;
1650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic volatile int g_1 = 1;
1660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovS4 a_s4[100];
1680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovS8 a_s8[100];
1690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17012c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov// Check that malloc poisons memory.
17112c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov// A lot of tests below depend on this.
17212c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy StepanovTEST(MemorySanitizerSanity, PoisonInMalloc) {
17312c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  int *x = (int*)malloc(sizeof(int));
17412c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  EXPECT_POISONED(*x);
17512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  free(x);
17612c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov}
17712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov
1780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, NegativeTest1) {
1790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *x = GetPoisoned<S4>();
1800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (g_one)
1810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    *x = 0;
18211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*x);
1830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
1840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, PositiveTest1) {
1860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // Load to store.
18711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S1>());
18811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S2>());
18911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S4>());
19011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S8>());
1910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // S->S conversions.
19311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S1>());
19411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S1>());
19511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S1>());
1960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
19711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S2>());
19811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S2>());
19911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S2>());
2000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
20111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S4>());
20211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S4>());
20311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S4>());
2040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
20511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S8>());
20611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S8>());
20711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<S8>());
2080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // ZExt
21011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U1>());
21111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U1>());
21211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U1>());
21311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U2>());
21411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U2>());
21511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<U4>());
2160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // Unary ops.
21811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(- *GetPoisoned<S4>());
2190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
22011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));
2210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  a_s4[g_zero] = 1 - *GetPoisoned<S4>();
2240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  a_s4[g_zero] = 1 + *GetPoisoned<S4>();
2250231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Phi1) {
2280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 c;
2290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (g_one) {
2300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    c = *GetPoisoned<S4>();
2310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  } else {
23212c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov    break_optimization(0);
2330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    c = 0;
2340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  }
23511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(c);
2360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Phi2) {
2390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 i = *GetPoisoned<S4>();
2400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 n = g_one;
24111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR(for (; i < g_one; i++););
24211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(i);
2430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
24511929000ec2919192b3be457f5a44c71ed55215eEvgeniy StepanovNOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(a1); }
24611929000ec2919192b3be457f5a44c71ed55215eEvgeniy StepanovNOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(a2); }
24711929000ec2919192b3be457f5a44c71ed55215eEvgeniy StepanovNOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(a3); }
2480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, ArgTest) {
2500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  Arg1ExpectUMR(*GetPoisoned<S4>());
2510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  Arg2ExpectUMR(0, *GetPoisoned<S4>());
2520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());
2530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, CallAndRet) {
2570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
2580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S1>();
2590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S2>();
2600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S4>();
2610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S8>();
2620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
26311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(ReturnPoisoned<S1>());
26411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(ReturnPoisoned<S2>());
26511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(ReturnPoisoned<S4>());
26611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(ReturnPoisoned<S8>());
2670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// malloc() in the following test may be optimized to produce a compile-time
2700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// undef value. Check that we trap on the volatile assignment anyway.
2710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DISABLED_MallocNoIdent) {
2720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *x = (int*)malloc(sizeof(S4));
27311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*x);
2740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  free(x);
2750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Malloc) {
2780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *x = (int*)Ident(malloc(sizeof(S4)));
27911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*x);
2800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  free(x);
2810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
2820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
2830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Realloc) {
2840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *x = (int*)Ident(realloc(0, sizeof(S4)));
28511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[0]);
2860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[0] = 1;
2870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
28811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.
28911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[1]);
2900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
29111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.
29211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[2]);
29311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[1]);
2940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[2] = 1;  // Init this here. Check that after realloc it is poisoned again.
2950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
29611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.
29711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[1]);
2980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
29911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[1]);
30011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x[2]);
3010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  free(x);
3020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Calloc) {
3050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *x = (int*)Ident(calloc(1, sizeof(S4)));
30611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*x);  // Should not be poisoned.
3070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // EXPECT_EQ(0, *x);
3080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  free(x);
3090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, AndOr) {
3120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U4 *p = GetPoisoned<U4>();
3130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // We poison two bytes in the midle of a 4-byte word to make the test
3140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // correct regardless of endianness.
3150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((U1*)p)[1] = 0;
3160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((U1*)p)[2] = 0xff;
31711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p & 0x00ffff00);
31811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p & 0x00ff0000);
31911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p & 0x0000ff00);
32011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p & 0xff000000);
32111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p & 0x000000ff);
32211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p & 0x0000ffff);
32311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p & 0xffff0000);
3240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
32511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p | 0xff0000ff);
32611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p | 0xff00ffff);
32711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*p | 0xffff00ff);
32811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p | 0xff000000);
32911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p | 0x000000ff);
33011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p | 0x0000ffff);
33111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*p | 0xffff0000);
3320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
33311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<bool>() & *GetPoisoned<bool>());
3340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
33711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovstatic bool applyNot(T value, T shadow) {
3380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_partial_poison(&value, &shadow, sizeof(T));
33911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  return !value;
3400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Not) {
34311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0x0, 0x0));
34411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFFFFFFFF, 0x0));
34511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(applyNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));
34611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0FFFFFFF));
34711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00FFFFFF));
34811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0000FFFF));
34911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00000000));
35011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(applyNot<U4>(0xFF000000, 0xFF000000));
35111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U4>(0xFF800000, 0xFF000000));
35211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(applyNot<U4>(0x00008000, 0x00008000));
35311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
35411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U1>(0x0, 0x0));
35511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0xFE));
35611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0x0));
35711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(applyNot<U1>(0xFF, 0xFF));
35811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
35911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-1)));
36011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-2)));
3610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Shift) {
3640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U4 *up = GetPoisoned<U4>();
3650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((U1*)up)[0] = 0;
3660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((U1*)up)[3] = 0xff;
36711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*up >> 30);
36811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*up >> 24);
36911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*up >> 23);
37011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*up >> 10);
3710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
37211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*up << 30);
37311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*up << 24);
37411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*up << 23);
37511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*up << 10);
3760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *sp = (S4*)up;
37811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*sp >> 30);
37911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*sp >> 24);
38011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*sp >> 23);
38111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*sp >> 10);
3820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  sp = GetPoisoned<S4>();
3840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((S1*)sp)[1] = 0;
3850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ((S1*)sp)[2] = 0;
38611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*sp >> 31);
3870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
38811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(100 >> *GetPoisoned<S4>());
38911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(100U >> *GetPoisoned<S4>());
3900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
3910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
3920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE static int GetPoisonedZero() {
3930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *zero = new int;
3940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *zero = 0;
3950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(zero, sizeof(*zero));
3960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = *zero;
3970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete zero;
3980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
3990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, LoadFromDirtyAddress) {
4020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *a = new int;
4030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *a = 0;
40412c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));
4050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete a;
4060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, StoreToDirtyAddress) {
4090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *a = new int;
41011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR(a[GetPoisonedZero()] = 0);
41112c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(a);
4120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete a;
4130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void StackTestFunc() {
4170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 p4;
4180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 ok4 = 1;
4190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S2 p2;
4200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S2 ok2 = 1;
4210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S1 p1;
4220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S1 ok1 = 1;
42312c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&p4);
42412c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&ok4);
42512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&p2);
42612c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&ok2);
42712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&p1);
42812c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&ok1);
4290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
43011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(p4);
43111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(p2);
43211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(p1);
43311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(ok1);
43411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(ok2);
43511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(ok4);
4360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, StackTest) {
4390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StackTestFunc();
4400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void StackStressFunc() {
4430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int foo[10000];
44412c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(foo);
4450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DISABLED_StackStressTest) {
4480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  for (int i = 0; i < 1000000; i++)
4490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    StackStressFunc();
4500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
4530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovvoid TestFloatingPoint() {
4540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  static volatile T v;
4550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  static T g[100];
45612c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&g);
4570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *x = GetPoisoned<T>();
4580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *y = GetPoisoned<T>(1);
45911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*x);
46011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED((long long)*x);
46111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED((int)*x);
4620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  g[0] = *x;
4630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  g[1] = *x + *y;
4640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  g[2] = *x - *y;
4650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  g[3] = *x * *y;
4660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, FloatingPointTest) {
4690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestFloatingPoint<float>();
4700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestFloatingPoint<double>();
4710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DynMem) {
4740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 x = 0;
4750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 *y = GetPoisoned<S4>();
4760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  memcpy(y, &x, g_one * sizeof(S4));
47711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*y);
4780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic char *DynRetTestStr;
4810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DynRet) {
4830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
4840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S8>();
48511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(clearenv());
4860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DynRet1) {
4900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
4910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ReturnPoisoned<S8>();
4920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
4930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct LargeStruct {
4950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 x[10];
4960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
4970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
4980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE
4990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovLargeStruct LargeRetTest() {
5000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LargeStruct res;
5010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[0] = *GetPoisoned<S4>();
5020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[1] = *GetPoisoned<S4>();
5030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[2] = *GetPoisoned<S4>();
5040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[3] = *GetPoisoned<S4>();
5050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[4] = *GetPoisoned<S4>();
5060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[5] = *GetPoisoned<S4>();
5070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[6] = *GetPoisoned<S4>();
5080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[7] = *GetPoisoned<S4>();
5090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[8] = *GetPoisoned<S4>();
5100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.x[9] = *GetPoisoned<S4>();
5110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
5120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, LargeRet) {
5150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LargeStruct a = LargeRetTest();
51611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(a.x[0]);
51711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(a.x[9]);
5180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, fread) {
5210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *x = new char[32];
5220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  FILE *f = fopen("/proc/self/stat", "r");
5230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(f);
5240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  fread(x, 1, 32, f);
52511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);
52611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[16]);
52711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[31]);
5280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  fclose(f);
5290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete x;
5300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, read) {
5330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *x = new char[32];
5340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int fd = open("/proc/self/stat", O_RDONLY);
5350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(fd > 0);
5360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int sz = read(fd, x, 32);
5370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(sz == 32);
53811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);
53911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[16]);
54011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[31]);
5410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  close(fd);
5420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete x;
5430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, pread) {
5460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *x = new char[32];
5470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int fd = open("/proc/self/stat", O_RDONLY);
5480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(fd > 0);
5490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int sz = pread(fd, x, 32, 0);
5500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(sz == 32);
55111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);
55211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[16]);
55311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[31]);
5540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  close(fd);
5550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete x;
5560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// FIXME: fails now.
5590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, DISABLED_ioctl) {
5600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct winsize ws;
5610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);
56211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(ws.ws_col);
5630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, readlink) {
5660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *x = new char[1000];
5670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  readlink("/proc/self/exe", x, 1000);
56811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[0]);
5690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete [] x;
5700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, stat) {
5740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct stat* st = new struct stat;
5750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = stat("/proc/self/stat", st);
5760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
57711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->st_dev);
57811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->st_mode);
57911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->st_size);
5800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, statfs) {
5830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct statfs* st = new struct statfs;
5840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = statfs("/", st);
5850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
58611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->f_type);
58711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->f_bfree);
58811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(st->f_namelen);
5890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
5900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
5910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, pipe) {
5920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* pipefd = new int[2];
5930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = pipe(pipefd);
5940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
59511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(pipefd[0]);
59611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(pipefd[1]);
5970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  close(pipefd[0]);
5980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  close(pipefd[1]);
5990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, getcwd) {
6020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char path[PATH_MAX + 1];
6030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* res = getcwd(path, sizeof(path));
6040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(res);
60511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(path[0]);
6060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6087eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy StepanovTEST(MemorySanitizer, getcwd_gnu) {
6097eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov  char* res = getcwd(NULL, 0);
6107eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov  assert(res);
6117eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov  EXPECT_NOT_POISONED(res[0]);
6127eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov  free(res);
6137eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov}
6147eed04c4dce69ad1e485edbf6dd963e176b52e0dEvgeniy Stepanov
6150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, realpath) {
6160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  const char* relpath = ".";
6170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char path[PATH_MAX + 1];
6180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* res = realpath(relpath, path);
6190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(res);
62011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(path[0]);
6210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, memcpy) {
6240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* x = new char[2];
6250231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* y = new char[2];
6260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[0] = 1;
6270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[1] = *GetPoisoned<char>();
6280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  memcpy(y, x, 2);
62911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y[0]);
63011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y[1]);
6310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, memmove) {
6340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* x = new char[2];
6350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* y = new char[2];
6360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[0] = 1;
6370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[1] = *GetPoisoned<char>();
6380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  memmove(y, x, 2);
63911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y[0]);
64011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y[1]);
6410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strdup) {
6440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *x = strdup("zzz");
64511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*x);
6460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  free(x);
6470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T, int size>
6500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovvoid TestOverlapMemmove() {
6510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *x = new T[size];
6520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(size >= 3);
6530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[2] = 0;
6540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  memmove(x, x + 1, (size - 1) * sizeof(T));
65511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x[1]);
6560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) {
6570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    // FIXME: under DR we will lose this information
6580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    // because accesses in memmove will unpoisin the shadow.
6590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    // We need to use our own memove implementation instead of libc's.
66011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_POISONED(x[0]);
66111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_POISONED(x[2]);
6620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  }
6630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete [] x;
6640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, overlap_memmove) {
6670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestOverlapMemmove<U1, 10>();
6680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestOverlapMemmove<U1, 1000>();
6690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestOverlapMemmove<U8, 4>();
6700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestOverlapMemmove<U8, 1000>();
6710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strcpy) {  // NOLINT
6740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* x = new char[3];
6750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* y = new char[3];
6760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[0] = 'a';
6770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[1] = *GetPoisoned<char>(1, 1);
6780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[2] = 0;
6790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  strcpy(y, x);  // NOLINT
68011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y[0]);
68111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y[1]);
68211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y[2]);
6830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strncpy) {  // NOLINT
6860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* x = new char[3];
6870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* y = new char[3];
6880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[0] = 'a';
6890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[1] = *GetPoisoned<char>(1, 1);
6900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x[2] = 0;
6910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  strncpy(y, x, 2);  // NOLINT
69211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y[0]);
69311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y[1]);
69411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y[2]);
6950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
6960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
6970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strtol) {
6980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *e;
6990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(1 == strtol("1", &e, 10));
70011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
7010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strtoll) {
7040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *e;
7050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(1 == strtoll("1", &e, 10));
70611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
7070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strtoul) {
7100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *e;
7110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(1 == strtoul("1", &e, 10));
71211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
7130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, strtoull) {
7160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *e;
7170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(1 == strtoull("1", &e, 10));
71811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
7190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
721e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovTEST(MemorySanitizer, strtod) {
722e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  char *e;
723e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  assert(0 != strtod("1.5", &e));
72411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
725e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
726e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
727e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovTEST(MemorySanitizer, strtof) {
728e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  char *e;
729e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  assert(0 != strtof("1.5", &e));
73011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
731e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
732e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
733e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovTEST(MemorySanitizer, strtold) {
734e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  char *e;
735e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  assert(0 != strtold("1.5", &e));
73611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((S8) e);
737e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
738e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
7390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, sprintf) {  // NOLINT
7400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char buff[10];
74112c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(buff);
74211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[0]);
7430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = sprintf(buff, "%d", 1234567);  // NOLINT
7440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(res == 7);
7450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[0] == '1');
7460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[1] == '2');
7470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[2] == '3');
7480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[6] == '7');
7490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[7] == 0);
75011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[8]);
7510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, snprintf) {
7540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char buff[10];
75512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(buff);
75611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[0]);
7570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = snprintf(buff, sizeof(buff), "%d", 1234567);
7580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(res == 7);
7590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[0] == '1');
7600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[1] == '2');
7610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[2] == '3');
7620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[6] == '7');
7630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[7] == 0);
76411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[8]);
7650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, swprintf) {
7680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  wchar_t buff[10];
7690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(sizeof(wchar_t) == 4);
77012c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(buff);
77111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[0]);
7720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = swprintf(buff, 9, L"%d", 1234567);
7730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(res == 7);
7740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[0] == '1');
7750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[1] == '2');
7760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[2] == '3');
7770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[6] == '7');
7780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(buff[7] == 0);
77911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(buff[8]);
7800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, wcstombs) {
7830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  const wchar_t *x = L"abc";
7840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char buff[10];
7850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = wcstombs(buff, x, 4);
7860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(res, 3);
7870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(buff[0], 'a');
7880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(buff[1], 'b');
7890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(buff[2], 'c');
7900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
7910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
7920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, gettimeofday) {
7930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct timeval tv;
7940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct timezone tz;
79512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&tv);
79612c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&tz);
7970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(sizeof(tv) == 16);
7980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(sizeof(tz) == 8);
79911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(tv.tv_sec);
80011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(tv.tv_usec);
80111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(tz.tz_minuteswest);
80211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(tz.tz_dsttime);
8030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(0 == gettimeofday(&tv, &tz));
80411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(tv.tv_sec);
80511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(tv.tv_usec);
80611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(tz.tz_minuteswest);
80711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(tz.tz_dsttime);
8080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovTEST(MemorySanitizer, localtime) {
8119358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  time_t t = 123;
8129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  struct tm *time = localtime(&t);
8139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  assert(time != 0);
8149358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time->tm_sec);
8159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time->tm_hour);
8169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time->tm_year);
8179358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time->tm_isdst);
8189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
8199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
8209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovTEST(MemorySanitizer, localtime_r) {
8219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  time_t t = 123;
8229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  struct tm time;
8239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  struct tm *res = localtime_r(&t, &time);
8249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  assert(res != 0);
8259358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time.tm_sec);
8269358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time.tm_hour);
8279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time.tm_year);
8289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  EXPECT_NOT_POISONED(time.tm_isdst);
8299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
8309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
8310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, mmap) {
8320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  const int size = 4096;
8330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  void *p1, *p2;
8340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
8350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(p1, size);
8360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  munmap(p1, size);
8370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  for (int i = 0; i < 1000; i++) {
8380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
8390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    if (p2 == p1)
8400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      break;
8410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    else
8420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      munmap(p2, size);
8430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  }
8440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (p1 == p2) {
84511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_NOT_POISONED(*(char*)p2);
8460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    munmap(p2, size);
8470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  }
8480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// FIXME: enable and add ecvt.
8510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// FIXME: check why msandr does nt handle fcvt.
8520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, fcvt) {
8530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a, b;
85412c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&a);
85512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&b);
85611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(a);
85711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(b);
8580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char *str = fcvt(12345.6789, 10, &a, &b);
85911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(a);
86011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(b);
8610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct StructWithDtor {
8640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ~StructWithDtor();
8650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
8660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE StructWithDtor::~StructWithDtor() {
86812c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(0);
8690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, Invoke) {
8720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructWithDtor s;  // Will cause the calls to become invokes.
87311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(0);
87411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<int>());
87511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(0);
87611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(*GetPoisoned<int>());
87711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(ReturnPoisoned<S4>());
8780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, ptrtoint) {
8810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // Test that shadow is propagated through pointer-to-integer conversion.
8820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  void* p = (void*)0xABCD;
8830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(((char*)&p) + 1, sizeof(p));
884250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  EXPECT_NOT_POISONED((((uintptr_t)p) & 0xFF) == 0);
8850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  void* q = (void*)0xABCD;
8870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&q, sizeof(q) - 1);
888250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  EXPECT_POISONED((((uintptr_t)q) & 0xFF) == 0);
8890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
8900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
8910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn2(int guard, ...) {
8920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
8930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
89411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
89511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
89611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
89711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, double));
8980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
8990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn(int guard, ...) {
9020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
9030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
90411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
90511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // The following call will overwrite __msan_param_tls.
9070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // Checks after it test that arg shadow was somehow saved across the call.
9080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());
90911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
91011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
9120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgTest) {
9150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
9160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* y = GetPoisoned<int>(4);
9170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn(1, 13, *x, 42, *y);
9180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_many(int guard, ...) {
9210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
9220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
92311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
92411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
92511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
92611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
92711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
92811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
92911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
93011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
93111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
93211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
9340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgManyTest) {
9370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
9380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* y = GetPoisoned<int>(4);
9390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);
9400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_pass2(va_list vl) {
94311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
94411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
94511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_pass(int guard, ...) {
9490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
9500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
95111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_pass2(vl);
9530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
9540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgPass) {
9570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
9580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* y = GetPoisoned<int>(4);
9590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_pass(1, *x, 2, 3, *y);
9600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_copy2(va_list vl) {
96311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
96411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_copy(int guard, ...) {
9680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
9690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
97011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
97111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl2;
9730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_copy(vl2, vl);
9740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_copy2(vl2);
97511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
97611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
9770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
9780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgCopy) {
9810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
9820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* y = GetPoisoned<int>(4);
9830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_copy(1, 2, *x, 3, *y);
9840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_ptr(int guard, ...) {
9870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
9880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
98911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int*));
99011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int*));
99111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int*));
99211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, double*));
9930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
9940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
9950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
9960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgPtr) {
9970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int** x = GetPoisoned<int*>();
9980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  double** y = GetPoisoned<double*>(8);
9990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int z;
10000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_ptr(1, &z, *x, &z, *y);
10010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_overflow(int guard, ...) {
10040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
10050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
100611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
100711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
100811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
100911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
101011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
101111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
101211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
101311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
101411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
101511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
101611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, double));
101711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
101811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int*));
101911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
102011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
102111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
102211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
102311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, double));
102411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int*));
102511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
102611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
102711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, double));
102811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int*));
102911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov
103011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
103111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, double));
103211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int*));
10330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
10350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgOverflow) {
10380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
10390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  double* y = GetPoisoned<double>(8);
10400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int** p = GetPoisoned<int*>(16);
10410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int z;
10420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_overflow(1,
10430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      1, 2, *x, 4, 5, 6,
10440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,
10450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      // the following args will overflow for sure
10460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      *x, *y, *p,
10470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      7, 9.9, &z,
10480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov      *x, *y, *p);
10490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_tlsoverwrite2(int guard, ...) {
10520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
10530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
105411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(va_arg(vl, int));
10550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
10560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void vaargsfn_tlsoverwrite(int guard, ...) {
10590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // This call will overwrite TLS contents unless it's backed up somewhere.
10600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_tlsoverwrite2(2, 42);
10610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_list vl;
10620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_start(vl, guard);
106311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(va_arg(vl, int));
10640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  va_end(vl);
10650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, VAArgTLSOverwrite) {
10680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int* x = GetPoisoned<int>();
10690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  vaargsfn_tlsoverwrite(1, *x);
10700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct StructByVal {
10730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a, b, c, d, e, f;
10740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
10750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void StructByValTestFunc(struct StructByVal s) {
107711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s.a);
107811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s.b);
107911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s.c);
108011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s.d);
108111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s.e);
108211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s.f);
10830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void StructByValTestFunc1(struct StructByVal s) {
10860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructByValTestFunc(s);
10870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {
10900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructByValTestFunc(s);
10910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
10920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
10930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, StructByVal) {
10940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // Large aggregates are passed as "byval" pointer argument in LLVM.
10950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct StructByVal s;
10960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.a = 1;
10970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.b = *GetPoisoned<int>();
10980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.c = 2;
10990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.d = *GetPoisoned<int>();
11000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.e = 3;
11010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.f = *GetPoisoned<int>();
11020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructByValTestFunc(s);
11030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructByValTestFunc1(s);
11040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructByValTestFunc2(0, s);
11050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#if MSAN_HAS_M128
11090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return *a == *b; }
11100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return *a < *b; }
11110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, m128) {
11120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __m128i a = _mm_set1_epi16(0x1234);
11130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __m128i b = _mm_set1_epi16(0x7890);
111411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(m128Eq(&a, &b));
111511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(m128Lt(&a, &b));
11160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// FIXME: add more tests for __m128i.
11180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#endif  // MSAN_HAS_M128
11190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// We should not complain when copying this poisoned hole.
11210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct StructWithHole {
11220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U4  a;
11230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // 4-byte hole.
11240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U8  b;
11250231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE StructWithHole ReturnStructWithHole() {
11280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructWithHole res;
11290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&res, sizeof(res));
11300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.a = 1;
11310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.b = 2;
11320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
11330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, StructWithHole) {
11360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructWithHole a = ReturnStructWithHole();
113712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&a);
11380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate <class T>
11410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE T ReturnStruct() {
11420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T res;
11430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&res, sizeof(res));
11440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.a = 1;
11450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
11460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate <class T>
11490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void TestReturnStruct() {
11500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T s1 = ReturnStruct<T>();
115111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s1.a);
115211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s1.b);
11530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS1 {
11560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a, b, c;
11570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS2 {
11590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int b, a, c;
11600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS3 {
11620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int b, c, a;
11630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS4 {
11650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int c, b, a;
11660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS5 {
11690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a;
11700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  float b;
11710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS6 {
11730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a;
11740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  double b;
11750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS7 {
11770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8 b;
11780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int a;
11790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct SSS8 {
11810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S2 b;
11820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8 a;
11830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
11840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, IntStruct3) {
11860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS1>();
11870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS2>();
11880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS3>();
11890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS4>();
11900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS5>();
11910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS6>();
11920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS7>();
11930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  TestReturnStruct<SSS8>();
11940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
11950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
11960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct LongStruct {
11970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U1 a1, b1;
11980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U2 a2, b2;
11990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U4 a4, b4;
12000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U8 a8, b8;
12010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
12020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
12030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE LongStruct ReturnLongStruct1() {
12040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LongStruct res;
12050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&res, sizeof(res));
12060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.a1 = res.a2 = res.a4 = res.a8 = 111;
12070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // leaves b1, .., b8 poisoned.
12080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
12090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
12100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
12110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE LongStruct ReturnLongStruct2() {
12120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LongStruct res;
12130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&res, sizeof(res));
12140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res.b1 = res.b2 = res.b4 = res.b8 = 111;
12150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // leaves a1, .., a8 poisoned.
12160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
12170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
12180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
12190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, LongStruct) {
12200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LongStruct s1 = ReturnLongStruct1();
12210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_print_shadow(&s1, sizeof(s1));
122211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s1.a1);
122311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s1.a2);
122411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s1.a4);
122511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s1.a8);
12260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
122711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s1.b1);
122811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s1.b2);
122911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s1.b4);
123011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s1.b8);
12310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
12320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  LongStruct s2 = ReturnLongStruct2();
12330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_print_shadow(&s2, sizeof(s2));
123411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s2.b1);
123511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s2.b2);
123611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s2.b4);
123711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s2.b8);
12380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
123911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s2.a1);
124011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s2.a2);
124111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s2.a4);
124211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s2.a8);
12430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
12440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
12450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, getrlimit) {
12460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct rlimit limit;
12470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&limit, sizeof(limit));
12480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int result = getrlimit(RLIMIT_DATA, &limit);
12490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(result == 0);
12500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  volatile rlim_t t;
12510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  t = limit.rlim_cur;
12520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  t = limit.rlim_max;
12530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
12540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1255e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovTEST(MemorySanitizer, getrusage) {
1256e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  struct rusage usage;
1257e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  __msan_poison(&usage, sizeof(usage));
1258e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  int result = getrusage(RUSAGE_SELF, &usage);
1259e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  assert(result == 0);
1260e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  volatile struct timeval t;
126111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_utime.tv_sec);
126211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_utime.tv_usec);
126311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_stime.tv_sec);
126411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_stime.tv_usec);
126511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_maxrss);
126611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_minflt);
126711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_majflt);
126811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_inblock);
126911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_oublock);
127011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_nvcsw);
127111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(usage.ru_nivcsw);
1272e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
1273e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
1274e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanovstatic void dladdr_testfn() {}
1275e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
1276e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovTEST(MemorySanitizer, dladdr) {
1277e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  Dl_info info;
1278e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  __msan_poison(&info, sizeof(info));
1279e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  int result = dladdr((const void*)dladdr_testfn, &info);
1280e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  assert(result != 0);
128111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((unsigned long)info.dli_fname);
1282e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  if (info.dli_fname)
128311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_NOT_POISONED(strlen(info.dli_fname));
128411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((unsigned long)info.dli_fbase);
128511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((unsigned long)info.dli_sname);
1286e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  if (info.dli_sname)
128711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov    EXPECT_NOT_POISONED(strlen(info.dli_sname));
128811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED((unsigned long)info.dli_saddr);
1289e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
1290e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
12910f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner#ifdef __GLIBC__
12920f92deb81207c80481ff0257fbaba640fe669633Reid Klecknerextern "C" {
12930f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  extern void *__libc_stack_end;
12940f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner}
12950f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
12960f92deb81207c80481ff0257fbaba640fe669633Reid Klecknerstatic char **GetArgv(void) {
12970f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  uintptr_t *stack_end = (uintptr_t *)__libc_stack_end;
12980f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  return (char**)(stack_end + 1);
12990f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner}
13000f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
13010f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner#else  // __GLIBC__
13020f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner# error "TODO: port this"
13030f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner#endif
13040f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
13050f92deb81207c80481ff0257fbaba640fe669633Reid KlecknerTEST(MemorySanitizer, dlopen) {
13060f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // Compute the path to our loadable DSO.  We assume it's in the same
13070f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // directory.  Only use string routines that we intercept so far to do this.
13080f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  char **argv = GetArgv();
13090f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  const char *basename = "libmsan_loadable.x86_64.so";
13100f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  size_t path_max = strlen(argv[0]) + 1 + strlen(basename) + 1;
13110f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  char *path = new char[path_max];
13120f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  char *last_slash = strrchr(argv[0], '/');
13130f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  assert(last_slash);
13140f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  snprintf(path, path_max, "%.*s/%s", int(last_slash - argv[0]),
13150f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner           argv[0], basename);
13160f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
13170f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // We need to clear shadow for globals when doing dlopen.  In order to test
13180f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // this, we have to poison the shadow for the DSO before we load it.  In
13190f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // general this is difficult, but the loader tends to reload things in the
13200f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // same place, so we open, close, and then reopen.  The global should always
13210f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  // start out clean after dlopen.
13220f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  for (int i = 0; i < 2; i++) {
13230f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    void *lib = dlopen(path, RTLD_LAZY);
13240f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    if (lib == NULL) {
13250f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner      printf("dlerror: %s\n", dlerror());
13260f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner      assert(lib != NULL);
13270f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    }
13280f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    void **(*get_dso_global)() = (void **(*)())dlsym(lib, "get_dso_global");
13290f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    assert(get_dso_global);
13300f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    void **dso_global = get_dso_global();
13310f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    EXPECT_NOT_POISONED(*dso_global);
13320f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    __msan_poison(dso_global, sizeof(*dso_global));
13330f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    EXPECT_POISONED(*dso_global);
13340f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner    dlclose(lib);
13350f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  }
13360f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
13370f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner  delete[] path;
13380f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner}
13390f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner
1340996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy StepanovTEST(MemorySanitizer, scanf) {
1341996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  const char *input = "42 hello";
1342996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  int* d = new int;
1343996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  char* s = new char[7];
1344996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  int res = sscanf(input, "%d %5s", d, s);
1345996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  printf("res %d\n", res);
1346996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  assert(res == 2);
134711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*d);
134811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[0]);
134911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[1]);
135011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[2]);
135111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[3]);
135211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[4]);
135311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[5]);
135411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s[6]);
1355996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  delete s;
1356996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  delete d;
1357996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}
1358996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
13590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void* SimpleThread_threadfn(void* data) {
13600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return new int;
13610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
13620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
13630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, SimpleThread) {
13640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  pthread_t t;
13650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  void* p;
13660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
13670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
13680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  res = pthread_join(t, &p);
13690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
13700231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component())  // FIXME: intercept pthread_join (?).
13710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    __msan_unpoison(&p, sizeof(p));
13720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete (int*)p;
13730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
13740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
13750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, uname) {
13760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  struct utsname u;
13770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = uname(&u);
13780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  assert(!res);
137911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(u.sysname));
138011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(u.nodename));
138111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(u.release));
138211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(u.version));
138311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(u.machine));
13840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
13850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
138695d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy StepanovTEST(MemorySanitizer, gethostname) {
138795d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  char buf[100];
138895d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  int res = gethostname(buf, 100);
138995d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  assert(!res);
139095d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  EXPECT_NOT_POISONED(strlen(buf));
139195d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov}
139295d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov
13930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T>
139411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanovstatic bool applySlt(T value, T shadow) {
13950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_partial_poison(&value, &shadow, sizeof(T));
13960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  volatile bool zzz = true;
13970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of
13980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // a shift-and-trunc to get at the highest bit.
139911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  volatile bool v = value < 0 || zzz;
140011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  return v;
14010231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
14020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
14030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizer, SignedCompareWithZero) {
140411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xF));
140511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFF));
140611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFFFFFF));
140711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0x7FFFFFF));
140811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR(applySlt<S4>(0xF, 0x80FFFFFF));
140911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR(applySlt<S4>(0xF, 0xFFFFFFFF));
14100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
14110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
14129a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanovtemplate <class T, class S>
14139a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanovstatic T poisoned(T Va, S Sa) {
14149a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  char SIZE_CHECK1[(ssize_t)sizeof(T) - (ssize_t)sizeof(S)];
14159a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  char SIZE_CHECK2[(ssize_t)sizeof(S) - (ssize_t)sizeof(T)];
14169a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  T a;
14179a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  a = Va;
14189a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  __msan_partial_poison(&a, &Sa, sizeof(T));
14199a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  return a;
14209a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov}
14219a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14229a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy StepanovTEST(MemorySanitizer, ICmpRelational) {
14239a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0, 0) < poisoned(0, 0));
14249a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0U, 0) < poisoned(0U, 0));
14259a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) < poisoned(0LL, 0LLU));
14269a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) < poisoned(0LLU, 0LLU));
14279a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFF, 0xFF) < poisoned(0xFF, 0xFF));
14289a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <
14299a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
14309a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <
14319a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(-1, 0xFFFFFFFFU));
14329a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14339a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0, 0) <= poisoned(0, 0));
14349a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0U, 0) <= poisoned(0U, 0));
14359a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) <= poisoned(0LL, 0LLU));
14369a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) <= poisoned(0LLU, 0LLU));
14379a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFF, 0xFF) <= poisoned(0xFF, 0xFF));
14389a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <=
14399a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
14409a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <=
14419a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(-1, 0xFFFFFFFFU));
14429a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14439a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0, 0) > poisoned(0, 0));
14449a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0U, 0) > poisoned(0U, 0));
14459a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) > poisoned(0LL, 0LLU));
14469a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) > poisoned(0LLU, 0LLU));
14479a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFF, 0xFF) > poisoned(0xFF, 0xFF));
14489a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >
14499a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
14509a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >
14519a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(-1, 0xFFFFFFFFU));
14529a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14539a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0, 0) >= poisoned(0, 0));
14549a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0U, 0) >= poisoned(0U, 0));
14559a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) >= poisoned(0LL, 0LLU));
14569a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) >= poisoned(0LLU, 0LLU));
14579a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFF, 0xFF) >= poisoned(0xFF, 0xFF));
14589a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >=
14599a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
14609a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >=
14619a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(-1, 0xFFFFFFFFU));
14629a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14639a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(6, 0xF) > poisoned(7, 0));
14649a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(0xF, 0xF) > poisoned(7, 0));
14659a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14669a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(-1, 0x80000000U) >= poisoned(-1, 0U));
14679a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov}
14689a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14699a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov#if MSAN_HAS_M128
14709a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy StepanovTEST(MemorySanitizer, ICmpVectorRelational) {
14719a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)) <
14729a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                      poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)));
14739a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_NOT_POISONED(poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)) <
14749a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                      poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)));
14759a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)) <
14769a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)));
14779a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov  EXPECT_POISONED(poisoned(_mm_set1_epi16(6), _mm_set1_epi16(0xF)) >
14789a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov                  poisoned(_mm_set1_epi16(7), _mm_set1_epi16(0)));
14799a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov}
14809a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov#endif
14819a22a3dab8a3284af86203843a41e2b35e617b09Evgeniy Stepanov
14822efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov// Volatile bitfield store is implemented as load-mask-store
14832efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov// Test that we don't warn on the store of (uninitialized) padding.
14842efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanovstruct VolatileBitfieldStruct {
14852efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov  volatile unsigned x : 1;
14862efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov  unsigned y : 1;
14872efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov};
14882efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov
14892efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy StepanovTEST(MemorySanitizer, VolatileBitfield) {
14902efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov  VolatileBitfieldStruct *S = new VolatileBitfieldStruct;
14912efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov  S->x = 1;
149202f4a942bff84f1266571740456dd9baa230d87bEvgeniy Stepanov  EXPECT_NOT_POISONED((unsigned)S->x);
149302f4a942bff84f1266571740456dd9baa230d87bEvgeniy Stepanov  EXPECT_POISONED((unsigned)S->y);
14942efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov}
14952efa1420ffc6b42c22b57de2bdf577d6390e137eEvgeniy Stepanov
14960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerDr, StoreInDSOTest) {
14970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
14980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char* s = new char[10];
14990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  dso_memfill(s, 9);
150011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(s[5]);
150111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(s[9]);
15020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovint return_poisoned_int() {
15050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return ReturnPoisoned<U8>();
15060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerDr, ReturnFromDSOTest) {
15090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
151011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(dso_callfn(return_poisoned_int));
15110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE int TrashParamTLS(long long x, long long y, long long z) {  //NOLINT
151411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(x);
151511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(y);
151611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED(z);
15170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return 0;
15180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic int CheckParamTLS(long long x, long long y, long long z) {  //NOLINT
152111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x);
152211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(y);
152311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(z);
15240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return 0;
15250231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerDr, CallFromDSOTest) {
15280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
15290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8* x = GetPoisoned<S8>();
15300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8* y = GetPoisoned<S8>();
15310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8* z = GetPoisoned<S8>();
153211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(TrashParamTLS(*x, *y, *z));
153311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(dso_callfn1(CheckParamTLS));
15340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstatic void StackStoreInDSOFn(int* x, int* y) {
153711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*x);
153811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(*y);
15390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerDr, StackStoreInDSOTest) {
15420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!__msan_has_dynamic_component()) return;
15430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  dso_stack_store(StackStoreInDSOFn, 1);
15440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, SetGet) {
15470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
15480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
15490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int x;
15500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(&x, sizeof(x), 1234);
15510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(1234, __msan_get_origin(&x));
15520231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(&x, sizeof(x), 5678);
15530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(5678, __msan_get_origin(&x));
15540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(&x, sizeof(x), 0);
15550231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(0, __msan_get_origin(&x));
15560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15570231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovnamespace {
15590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovstruct S {
15600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U4 dummy;
15610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U2 a;
15620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  U2 b;
15630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov};
15640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// http://code.google.com/p/memory-sanitizer/issues/detail?id=6
15660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, DISABLED_InitializedStoreDoesNotChangeOrigin) {
15670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
15680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S s;
1570250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = rand();  // NOLINT
15710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.a = *GetPoisonedO<U2>(0, origin);
15720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(origin, __msan_get_origin(&s.a));
15730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(origin, __msan_get_origin(&s.b));
15740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  s.b = 42;
15760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(origin, __msan_get_origin(&s.a));
15770231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(origin, __msan_get_origin(&s.b));
15780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
15790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}  // namespace
15800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T, class BinaryOp>
15820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovINLINE
15830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovvoid BinaryOpOriginTest(BinaryOp op) {
1584250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 ox = rand();  //NOLINT
1585250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 oy = rand();  //NOLINT
15860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *x = GetPoisonedO<T>(0, ox, 0);
15870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *y = GetPoisonedO<T>(1, oy, 0);
15880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *z = GetPoisonedO<T>(2, 0, 0);
15890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *z = op(*x, *y);
1591250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __msan_get_origin(z);
159211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*z, origin);
15930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(true, origin == ox || origin == oy);
15940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
15950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // y is poisoned, x is not.
15960231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *x = 10101;
15970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *y = *GetPoisonedO<T>(1, oy);
159812c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(x);
15990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(z, sizeof(*z), 0);
16000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *z = op(*x, *y);
160111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*z, oy);
16020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(__msan_get_origin(z), oy);
16030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16040231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // x is poisoned, y is not.
16050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *x = *GetPoisonedO<T>(0, ox);
16060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *y = 10101010;
160712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(y);
16080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(z, sizeof(*z), 0);
16090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  *z = op(*x, *y);
161011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*z, ox);
16110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  EXPECT_EQ(__msan_get_origin(z), ox);
16120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }
16150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }
16160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }
16170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }
16180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T AND(const T &a, const T&b) { return a & b; }
16190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T> INLINE T OR (const T &a, const T&b) { return a | b; }
16200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, BinaryOp) {
16220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
16230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<S8>(XOR<S8>);
16240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<U8>(ADD<U8>);
16250231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<S4>(SUB<S4>);
16260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<S4>(MUL<S4>);
16270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<U4>(OR<U4>);
16280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<U4>(AND<U4>);
16290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<double>(ADD<U4>);
16300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<float>(ADD<S4>);
16310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<double>(ADD<double>);
16320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  BinaryOpOriginTest<float>(ADD<double>);
16330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16350231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Unary) {
16360231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
163711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
163811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
163911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
164011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
16410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
164211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
164311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
164411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
164511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
16460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
164711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
164811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
164911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
165011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
16510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
165211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
165311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
165411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
165511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
16560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
165711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O((void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);
165811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O((U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);
16590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, EQ) {
16620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
166311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);
166411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);
166511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);
16660231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, DIV) {
16690231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
167011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);
167111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  unsigned o = __LINE__;
167211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR_O(volatile unsigned y = 100 / *GetPoisonedO<S4>(0, o, 1), o);
16730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, SHIFT) {
16760231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
167711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);
167811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);
167911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);
168011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);
168111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(-10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);
168211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(-10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);
16830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
16840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
16850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovtemplate<class T, int N>
16860231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovvoid MemCpyTest() {
16870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int ox = __LINE__;
16880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *x = new T[N];
16890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *y = new T[N];
16900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  T *z = new T[N];
16910231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(x, N * sizeof(T));
16920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(x, N * sizeof(T), ox);
16930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(y, N * sizeof(T), 777777);
16940231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(z, N * sizeof(T), 888888);
169511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x);
169611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  memcpy(y, x, N * sizeof(T));
169711929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(y[0], ox);
169811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(y[N/2], ox);
169911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(y[N-1], ox);
170011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(x);
170111929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  memmove(z, x, N * sizeof(T));
170211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(z[0], ox);
170311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(z[N/2], ox);
170411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(z[N-1], ox);
17050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, LargeMemCpy) {
17080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
17090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  MemCpyTest<U1, 10000>();
17100231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  MemCpyTest<U8, 10000>();
17110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, SmallMemCpy) {
17140231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
17150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  MemCpyTest<U8, 1>();
17160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  MemCpyTest<U8, 2>();
17170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  MemCpyTest<U8, 3>();
17180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Select) {
17210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
172211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
172311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
17240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S4 x;
172512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&x);
17260231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
17270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
172811929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
172911929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);
17300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovextern "C"
173311929000ec2919192b3be457f5a44c71ed55215eEvgeniy StepanovNOINLINE char AllocaTO() {
17340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int ar[100];
173512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(ar);
173611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  return ar[10];
17370231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  // fprintf(stderr, "Descr: %s\n",
17380231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  //        __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
17390231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17400231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17410231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Alloca) {
17420231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
174311929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
174411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
174511929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
174611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
17470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov// FIXME: replace with a lit-like test.
17500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) {
17510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
175211929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_DEATH(AllocaTO(), "ORIGIN: stack allocation: ar@AllocaTO");
17530231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17540231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1755250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovNOINLINE int RetvalOriginTest(U4 origin) {
17560231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *a = new int;
175712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(a);
17580231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(a, sizeof(*a), origin);
17590231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = *a;
17600231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete a;
17610231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
17620231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17630231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17640231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Retval) {
17650231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
176611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
17670231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17680231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
1769250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovNOINLINE void ParamOriginTest(int param, U4 origin) {
177011929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(param, origin);
17710231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17720231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17730231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Param) {
17740231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
17750231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *a = new int;
1776250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __LINE__;
177712c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(a);
17780231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(a, sizeof(*a), origin);
17790231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  ParamOriginTest(*a, origin);
17800231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete a;
17810231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17820231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17830231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, Invoke) {
17840231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (!TrackingOrigins()) return;
17850231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  StructWithDtor s;  // Will cause the calls to become invokes.
178611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
17870231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17880231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17890231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, strlen) {
17900231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  S8 alignment;
179112c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(&alignment);
17920231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  char x[4] = {'a', 'b', 0, 0};
17930231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&x[2], 1);
1794250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __LINE__;
17950231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(x, sizeof(x), origin);
179611929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR_O(volatile unsigned y = strlen(x), origin);
17970231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
17980231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
17990231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, wcslen) {
18000231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  wchar_t w[3] = {'a', 'b', 0};
1801250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __LINE__;
18020231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(w, sizeof(w), origin);
18030231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&w[2], sizeof(wchar_t));
180411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_UMR_O(volatile unsigned y = wcslen(w), origin);
18050231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
18060231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
18070231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#if MSAN_HAS_M128
18080231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerOrigins, StoreIntrinsic) {
18090231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __m128 x, y;
1810250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  U4 origin = __LINE__;
18110231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_set_origin(&x, sizeof(x), origin);
18120231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __msan_poison(&x, sizeof(x));
18130231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  __builtin_ia32_storeups((float*)&y, x);
181411929000ec2919192b3be457f5a44c71ed55215eEvgeniy Stepanov  EXPECT_POISONED_O(y, origin);
18150231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
18160231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov#endif
18170231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
18180231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovNOINLINE void RecursiveMalloc(int depth) {
18190231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  static int count;
18200231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  count++;
18210231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if ((count % (1024 * 1024)) == 0)
18220231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    printf("RecursiveMalloc: %d\n", count);
18230231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *x1 = new int;
18240231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int *x2 = new int;
182512c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(x1);
182612c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanov  break_optimization(x2);
18270231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  if (depth > 0) {
18280231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    RecursiveMalloc(depth-1);
18290231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov    RecursiveMalloc(depth-1);
18300231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  }
18310231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete x1;
18320231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  delete x2;
18330231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
18340231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
183565199f1b253c4bfb225805629217acb8f0b1e185Kostya SerebryanyTEST(MemorySanitizer, CallocOverflow) {
183665199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany  size_t kArraySize = 4096;
183765199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany  volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
183865199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany  volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
183965199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany  void *p = calloc(kArraySize, kArraySize2);  // Should return 0.
184065199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany  EXPECT_EQ(0L, Ident(p));
184165199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany}
184265199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany
18430231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy StepanovTEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
18440231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  RecursiveMalloc(22);
18450231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
18460231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov
18470231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanovint main(int argc, char **argv) {
18480231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  testing::InitGoogleTest(&argc, argv);
18490231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  int res = RUN_ALL_TESTS();
18500231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov  return res;
18510231c50f42e735739041f3b4b4ce17e1742bed69Evgeniy Stepanov}
1852