Use DoNotOptimize to prevent new/delete elision.
The new/delete tests, in particular those which test replacement functions, often fail when the optimizer is enabled because the calls to new/delete may be optimized away, regardless of their side-effects. This patch converts the tests to use DoNotOptimize in order to prevent the elision. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@328245 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -69,31 +69,32 @@ void operator delete [] (void* p, std::align_val_t) TEST_NOEXCEPT
|
|||||||
struct alignas(OverAligned) A {};
|
struct alignas(OverAligned) A {};
|
||||||
struct alignas(std::max_align_t) B {};
|
struct alignas(std::max_align_t) B {};
|
||||||
|
|
||||||
B* volatile b; // Escape the memory
|
|
||||||
A* volatile a;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
{
|
{
|
||||||
b = new B[2];
|
B *b = new B[2];
|
||||||
|
DoNotOptimize(b);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
|
|
||||||
delete [] b;
|
delete [] b;
|
||||||
|
DoNotOptimize(b);
|
||||||
assert(1 == unsized_delete_called);
|
assert(1 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
{
|
{
|
||||||
a = new A[2];
|
A *a = new A[2];
|
||||||
|
DoNotOptimize(a);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
|
|
||||||
delete [] a;
|
delete [] a;
|
||||||
|
DoNotOptimize(a);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(1 == aligned_delete_called);
|
assert(1 == aligned_delete_called);
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ void* operator new[](std::size_t s, std::align_val_t a) TEST_THROW_SPEC(std::bad
|
|||||||
assert(s <= sizeof(DummyData));
|
assert(s <= sizeof(DummyData));
|
||||||
assert(static_cast<std::size_t>(a) == OverAligned);
|
assert(static_cast<std::size_t>(a) == OverAligned);
|
||||||
++new_called;
|
++new_called;
|
||||||
return DummyData;
|
void *Ret = DummyData;
|
||||||
|
DoNotOptimize(Ret);
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT
|
void operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT
|
||||||
@@ -61,6 +63,7 @@ void operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT
|
|||||||
assert(new_called == 1);
|
assert(new_called == 1);
|
||||||
--new_called;
|
--new_called;
|
||||||
assert(p == DummyData);
|
assert(p == DummyData);
|
||||||
|
DoNotOptimize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ int main()
|
|||||||
std::set_new_handler(my_new_handler);
|
std::set_new_handler(my_new_handler);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
void* volatile vp = operator new[] (std::numeric_limits<std::size_t>::max());
|
void* vp = operator new[] (std::numeric_limits<std::size_t>::max());
|
||||||
((void)vp);
|
DoNotOptimize(vp);
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
catch (std::bad_alloc&)
|
catch (std::bad_alloc&)
|
||||||
@@ -55,8 +55,10 @@ int main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
A* ap = new A[3];
|
A* ap = new A[3];
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed == 3);
|
assert(A_constructed == 3);
|
||||||
delete [] ap;
|
delete [] ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(A_constructed == 0);
|
assert(A_constructed == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ int main()
|
|||||||
try
|
try
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
|
void* vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
|
||||||
|
DoNotOptimize(vp);
|
||||||
assert(new_handler_called == 1);
|
assert(new_handler_called == 1);
|
||||||
assert(vp == 0);
|
assert(vp == 0);
|
||||||
}
|
}
|
||||||
@@ -53,8 +54,10 @@ int main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
A* ap = new(std::nothrow) A[3];
|
A* ap = new(std::nothrow) A[3];
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed == 3);
|
assert(A_constructed == 3);
|
||||||
delete [] ap;
|
delete [] ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(A_constructed == 0);
|
assert(A_constructed == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void operator delete(void* p) TEST_NOEXCEPT
|
|||||||
std::free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile int A_constructed = 0;
|
int A_constructed = 0;
|
||||||
|
|
||||||
struct A
|
struct A
|
||||||
{
|
{
|
||||||
@@ -44,15 +44,15 @@ struct A
|
|||||||
~A() {--A_constructed;}
|
~A() {--A_constructed;}
|
||||||
};
|
};
|
||||||
|
|
||||||
A* volatile ap;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
ap = new (std::nothrow) A[3];
|
A *ap = new (std::nothrow) A[3];
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed == 3);
|
assert(A_constructed == 3);
|
||||||
assert(new_called);
|
assert(new_called);
|
||||||
delete [] ap;
|
delete [] ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(A_constructed == 0);
|
assert(A_constructed == 0);
|
||||||
assert(!new_called);
|
assert(!new_called);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
|
||||||
volatile int new_called = 0;
|
int new_called = 0;
|
||||||
|
|
||||||
void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
|
void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
|
||||||
{
|
{
|
||||||
@@ -45,15 +45,15 @@ struct A
|
|||||||
~A() {--A_constructed;}
|
~A() {--A_constructed;}
|
||||||
};
|
};
|
||||||
|
|
||||||
A* volatile ap;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
ap = new A[3];
|
A *ap = new A[3];
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed == 3);
|
assert(A_constructed == 3);
|
||||||
assert(new_called == 1);
|
assert(new_called == 1);
|
||||||
delete [] ap;
|
delete [] ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(A_constructed == 0);
|
assert(A_constructed == 0);
|
||||||
assert(new_called == 0);
|
assert(new_called == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,15 +46,15 @@ void operator delete[](void* p, const std::nothrow_t&) TEST_NOEXCEPT
|
|||||||
// selected.
|
// selected.
|
||||||
struct A { ~A() {} };
|
struct A { ~A() {} };
|
||||||
|
|
||||||
A *volatile x;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
x = new A[3];
|
A *x = new A[3];
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == delete_called);
|
assert(0 == delete_called);
|
||||||
assert(0 == delete_nothrow_called);
|
assert(0 == delete_nothrow_called);
|
||||||
|
|
||||||
delete [] x;
|
delete [] x;
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(1 == delete_called);
|
assert(1 == delete_called);
|
||||||
assert(0 == delete_nothrow_called);
|
assert(0 == delete_nothrow_called);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,31 +68,32 @@ void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT
|
|||||||
struct alignas(OverAligned) A {};
|
struct alignas(OverAligned) A {};
|
||||||
struct alignas(std::max_align_t) B {};
|
struct alignas(std::max_align_t) B {};
|
||||||
|
|
||||||
B* volatile bp;
|
|
||||||
A* volatile ap;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
{
|
{
|
||||||
bp = new B;
|
B *bp = new B;
|
||||||
|
DoNotOptimize(bp);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
|
|
||||||
delete bp;
|
delete bp;
|
||||||
|
DoNotOptimize(bp);
|
||||||
assert(1 == unsized_delete_called);
|
assert(1 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
{
|
{
|
||||||
ap = new A;
|
A *ap = new A;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == aligned_delete_called);
|
assert(0 == aligned_delete_called);
|
||||||
|
|
||||||
delete ap;
|
delete ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(1 == aligned_delete_called);
|
assert(1 == aligned_delete_called);
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ void* operator new(std::size_t s, std::align_val_t a) TEST_THROW_SPEC(std::bad_a
|
|||||||
assert(s <= sizeof(DummyData));
|
assert(s <= sizeof(DummyData));
|
||||||
assert(static_cast<std::size_t>(a) == OverAligned);
|
assert(static_cast<std::size_t>(a) == OverAligned);
|
||||||
++new_called;
|
++new_called;
|
||||||
return DummyData;
|
void *Ret = DummyData;
|
||||||
|
DoNotOptimize(Ret);
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT
|
void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT
|
||||||
@@ -61,6 +63,7 @@ void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT
|
|||||||
assert(new_called == 1);
|
assert(new_called == 1);
|
||||||
--new_called;
|
--new_called;
|
||||||
assert(p == DummyData);
|
assert(p == DummyData);
|
||||||
|
DoNotOptimize(DummyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ struct A
|
|||||||
~A() {A_constructed = false;}
|
~A() {A_constructed = false;}
|
||||||
};
|
};
|
||||||
|
|
||||||
A* volatile ap;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
ap = new (std::nothrow) A;
|
A *ap = new (std::nothrow) A;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed);
|
assert(A_constructed);
|
||||||
assert(new_called);
|
assert(new_called);
|
||||||
delete ap;
|
delete ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(!A_constructed);
|
assert(!A_constructed);
|
||||||
assert(!new_called);
|
assert(!new_called);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,15 +43,15 @@ struct A
|
|||||||
~A() {A_constructed = false;}
|
~A() {A_constructed = false;}
|
||||||
};
|
};
|
||||||
|
|
||||||
A *volatile ap;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
ap = new A;
|
A *ap = new A;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(ap);
|
assert(ap);
|
||||||
assert(A_constructed);
|
assert(A_constructed);
|
||||||
assert(new_called);
|
assert(new_called);
|
||||||
delete ap;
|
delete ap;
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(!A_constructed);
|
assert(!A_constructed);
|
||||||
assert(!new_called);
|
assert(!new_called);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,16 +44,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT
|
|||||||
std::free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int *volatile x;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
x = new int(42);
|
int *x = new int(42);
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == sized_delete_called);
|
assert(0 == sized_delete_called);
|
||||||
|
|
||||||
delete x;
|
delete x;
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(1 == unsized_delete_called);
|
assert(1 == unsized_delete_called);
|
||||||
assert(0 == sized_delete_called);
|
assert(0 == sized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
|
|||||||
@@ -49,16 +49,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT
|
|||||||
std::free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int *volatile x;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
x = new int(42);
|
int *x = new int(42);
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
assert(0 == sized_delete_called);
|
assert(0 == sized_delete_called);
|
||||||
|
|
||||||
delete x;
|
delete x;
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(1 == sized_delete_called);
|
assert(1 == sized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
|
|||||||
@@ -35,15 +35,15 @@ void operator delete(void* p, const std::nothrow_t&) TEST_NOEXCEPT
|
|||||||
std::free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int* volatile x;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
x = new int(42);
|
int *x = new int(42);
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == delete_called);
|
assert(0 == delete_called);
|
||||||
assert(0 == delete_nothrow_called);
|
assert(0 == delete_nothrow_called);
|
||||||
|
|
||||||
delete x;
|
delete x;
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(1 == delete_called);
|
assert(1 == delete_called);
|
||||||
assert(0 == delete_nothrow_called);
|
assert(0 == delete_nothrow_called);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,16 +62,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT
|
|||||||
std::free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int* volatile x;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
x = new int(42);
|
int *x = new int(42);
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(0 == sized_delete_called);
|
assert(0 == sized_delete_called);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
|
|
||||||
delete x;
|
delete x;
|
||||||
|
DoNotOptimize(x);
|
||||||
assert(1 == sized_delete_called);
|
assert(1 == sized_delete_called);
|
||||||
assert(0 == unsized_delete_called);
|
assert(0 == unsized_delete_called);
|
||||||
assert(0 == unsized_delete_nothrow_called);
|
assert(0 == unsized_delete_nothrow_called);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
#include "count_new.hpp"
|
#include "count_new.hpp"
|
||||||
@@ -59,7 +60,8 @@ void test_aligned() {
|
|||||||
assert(T::constructed == 0);
|
assert(T::constructed == 0);
|
||||||
globalMemCounter.last_new_size = 0;
|
globalMemCounter.last_new_size = 0;
|
||||||
globalMemCounter.last_new_align = 0;
|
globalMemCounter.last_new_align = 0;
|
||||||
T* volatile ap = a.allocate(3);
|
T* ap = a.allocate(3);
|
||||||
|
DoNotOptimize(ap);
|
||||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||||
assert(globalMemCounter.checkNewCalledEq(1));
|
assert(globalMemCounter.checkNewCalledEq(1));
|
||||||
assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
|
assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
|
||||||
@@ -79,6 +81,7 @@ void test_aligned() {
|
|||||||
globalMemCounter.last_new_size = 0;
|
globalMemCounter.last_new_size = 0;
|
||||||
globalMemCounter.last_new_align = 0;
|
globalMemCounter.last_new_align = 0;
|
||||||
T* volatile ap2 = a.allocate(11, (const void*)5);
|
T* volatile ap2 = a.allocate(11, (const void*)5);
|
||||||
|
DoNotOptimize(ap2);
|
||||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||||
assert(globalMemCounter.checkNewCalledEq(1));
|
assert(globalMemCounter.checkNewCalledEq(1));
|
||||||
assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
|
assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
|
||||||
@@ -87,6 +90,7 @@ void test_aligned() {
|
|||||||
assert(T::constructed == 0);
|
assert(T::constructed == 0);
|
||||||
globalMemCounter.last_delete_align = 0;
|
globalMemCounter.last_delete_align = 0;
|
||||||
a.deallocate(ap2, 11);
|
a.deallocate(ap2, 11);
|
||||||
|
DoNotOptimize(ap2);
|
||||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||||
assert(globalMemCounter.checkDeleteCalledEq(1));
|
assert(globalMemCounter.checkDeleteCalledEq(1));
|
||||||
assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
|
assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
|
||||||
|
|||||||
@@ -221,8 +221,18 @@ struct is_same<T, T> { enum {value = 1}; };
|
|||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
inline void DoNotOptimize(Tp const& value) {
|
inline
|
||||||
asm volatile("" : : "g"(value) : "memory");
|
void DoNotOptimize(Tp const& value) {
|
||||||
|
asm volatile("" : : "r,m"(value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Tp>
|
||||||
|
inline void DoNotOptimize(Tp& value) {
|
||||||
|
#if defined(__clang__)
|
||||||
|
asm volatile("" : "+r,m"(value) : : "memory");
|
||||||
|
#else
|
||||||
|
asm volatile("" : "+m,r"(value) : : "memory");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user