Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@@ -26,14 +26,10 @@ class Program
if (ThreadTest.Run() != Pass)
return Fail;
return Pass;
}
if (TimerTest.Run() != Pass)
return Fail;
public static bool IsRunnningOnWindows()
{
// Note: Environment.OSVersion is not yet available.
// This is a temporary hack that allows to skip Task related tests on Unix.
return System.IO.Path.DirectorySeparatorChar == '\\';
return Pass;
}
}
@@ -163,12 +159,6 @@ class ThreadStaticsTestWithTasks
public static void Run()
{
if (!Program.IsRunnningOnWindows())
{
// Tasks are not supported on Unix yet
return;
}
Task[] tasks = new Task[TotalTaskCount];
for (int i = 0; i < tasks.Length; ++i)
{
@@ -340,12 +330,6 @@ class ThreadTest
private static void TestIsBackgroundProperty()
{
if (!Program.IsRunnningOnWindows())
{
// This test uses tasks which are not supported on Unix yet
return;
}
// Thread created using Thread.Start
var t_event = new AutoResetEvent(false);
var t = new Thread(() => t_event.WaitOne());
@@ -576,3 +560,73 @@ class ThreadTest
}
}
}
class TimerTest
{
private static AutoResetEvent s_event;
private static Timer s_timer;
private static volatile int s_periodicTimerCount;
public static int Run()
{
s_event = new AutoResetEvent(false);
s_timer = new Timer(TimerCallback, null, 200, Timeout.Infinite);
bool timerFired = s_event.WaitOne(TimeSpan.FromSeconds(5));
if (!timerFired)
{
Console.WriteLine("The timer test failed: timer has not fired.");
return Program.Fail;
}
// Change the timer to a very long value
s_event.Reset();
s_timer.Change(3000000, Timeout.Infinite);
timerFired = s_event.WaitOne(500);
if (timerFired)
{
Console.WriteLine("The timer test failed: timer fired earlier than expected.");
return Program.Fail;
}
// Try change existing timer to a small value and make sure it fires
s_event.Reset();
s_timer.Change(200, Timeout.Infinite);
timerFired = s_event.WaitOne(TimeSpan.FromSeconds(5));
if (!timerFired)
{
Console.WriteLine("The timer test failed: failed to change the existing timer.");
return Program.Fail;
}
// Test a periodic timer
s_periodicTimerCount = 0;
s_event.Reset();
s_timer = new Timer(PeriodicTimerCallback, null, 200, 20);
while (s_periodicTimerCount < 3)
{
timerFired = s_event.WaitOne(TimeSpan.FromSeconds(5));
if (!timerFired)
{
Console.WriteLine("The timer test failed: the periodic timer has not fired.");
return Program.Fail;
}
}
// Stop the periodic timer
s_timer.Change(Timeout.Infinite, Timeout.Infinite);
return Program.Pass;
}
private static void TimerCallback(object state)
{
s_event.Set();
}
private static void PeriodicTimerCallback(object state)
{
Interlocked.Increment(ref s_periodicTimerCount);
s_event.Set();
}
}

View File

@@ -20,6 +20,8 @@ public class BringUpTest
static BringUpTest g = null;
static int finallyCounter = 0;
public static int Main()
{
if (string.Empty.Length > 0)
@@ -102,6 +104,27 @@ public class BringUpTest
counter++;
}
// test interaction of filters and finally clauses with GC
try
{
ThrowExcThroughMethodsWithFinalizers1("Main");
}
catch (Exception e) when (FilterWithGC() && counter++ > 0)
{
Console.WriteLine(e.Message);
if (e.Message != "ThrowExcThroughMethodsWithFinalizers2")
{
Console.WriteLine("Unexpected exception message!");
return Fail;
}
if (finallyCounter != 2)
{
Console.WriteLine("Finalizers didn't execute!");
return Fail;
}
counter++;
}
try
{
try
@@ -121,7 +144,7 @@ public class BringUpTest
counter++;
}
if (counter != 8)
if (counter != 10)
{
Console.WriteLine("Unexpected counter value");
return Fail;
@@ -129,4 +152,52 @@ public class BringUpTest
return Pass;
}
static void CreateSomeGarbage()
{
for (int i = 0; i < 100; i++)
{
string s = new string('.', 100);
}
}
static void ThrowExcThroughMethodsWithFinalizers1(string caller)
{
CreateSomeGarbage();
string s = caller + " + ThrowExcThroughMethodsWithFinalizers1";
CreateSomeGarbage();
try
{
ThrowExcThroughMethodsWithFinalizers2(s);
}
finally
{
Console.WriteLine("Executing finally in {0}", s);
finallyCounter++;
}
}
static void ThrowExcThroughMethodsWithFinalizers2(string caller)
{
CreateSomeGarbage();
string s = caller + " + ThrowExcThroughMethodsWithFinalizers2";
CreateSomeGarbage();
try
{
throw new Exception("ThrowExcThroughMethodsWithFinalizers2");
}
finally
{
Console.WriteLine("Executing finally in {0}", s);
finallyCounter++;
}
}
static bool FilterWithGC()
{
CreateSomeGarbage();
GC.Collect();
CreateSomeGarbage();
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,4 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<IlcArg Include="--usesharedgenerics" />
</ItemGroup>
<ItemGroup>
<Compile Include="*.cs" />
</ItemGroup>

View File

@@ -36,12 +36,36 @@ namespace PInvokeTests
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiString(string str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiStringOut(out string str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiStringRef(ref string str);
[DllImport("*", EntryPoint = "VerifyAnsiStringRef", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiStringInRef([In]ref string str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int VerifyUnicodeString(string str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int VerifyUnicodeStringOut(out string str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int VerifyUnicodeStringRef(ref string str);
[DllImport("*", EntryPoint = "VerifyUnicodeStringRef", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int VerifyUnicodeStringInRef([In]ref string str);
[DllImport("*", CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiStringArray([In, MarshalAs(UnmanagedType.LPArray)]string[] str);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern bool VerifyAnsiCharArrayIn(char[] a);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern bool VerifyAnsiCharArrayOut([Out]char[] a);
[DllImport("*", CharSet = CharSet.Ansi)]
private static extern void ToUpper([In, Out, MarshalAs(UnmanagedType.LPArray)]string[] str);
@@ -49,8 +73,23 @@ namespace PInvokeTests
private static extern bool VerifySizeParamIndex(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out byte[] arrByte, out byte arrSize);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, EntryPoint = "VerifyUnicodeStringBuilder")]
private static extern int VerifyUnicodeStringBuilder(StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, EntryPoint = "VerifyUnicodeStringBuilder")]
private static extern int VerifyUnicodeStringBuilderIn([In]StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int VerifyStringBuilder(StringBuilder sb);
private static extern int VerifyUnicodeStringBuilderOut([Out]StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "VerifyAnsiStringBuilder")]
private static extern int VerifyAnsiStringBuilder(StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "VerifyAnsiStringBuilder")]
private static extern int VerifyAnsiStringBuilderIn([In]StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int VerifyAnsiStringBuilderOut([Out]StringBuilder sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
public static extern bool SafeHandleTest(SafeMemoryHandle sh1, Int64 sh1Value);
@@ -70,6 +109,12 @@ namespace PInvokeTests
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool ReversePInvoke_String(Delegate_String del);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern Delegate_String GetDelegate();
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool Callback(ref Delegate_String d);
delegate void Delegate_Unused();
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern unsafe int* ReversePInvoke_Unused(Delegate_Unused del);
@@ -77,6 +122,9 @@ namespace PInvokeTests
[DllImport("*", CallingConvention = CallingConvention.StdCall, EntryPoint = "StructTest")]
static extern bool StructTest_Auto(AutoStruct ss);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool StructTest_Sequential2(NesterOfSequentialStruct.SequentialStruct ss);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool StructTest(SequentialStruct ss);
@@ -92,6 +140,47 @@ namespace PInvokeTests
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool StructTest_Nested(NestedStruct ns);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool StructTest_Array(SequentialStruct []ns, int length);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern bool IsNULL(char[] a);
[DllImport("*", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern bool IsNULL(String sb);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool IsNULL(Foo[] foo);
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool IsNULL(SequentialStruct[] foo);
[StructLayout(LayoutKind.Sequential, CharSet= CharSet.Ansi, Pack = 4)]
public unsafe struct InlineArrayStruct
{
public int f0;
public int f1;
public int f2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public short[] inlineArray;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string inlineString;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
public unsafe struct InlineUnicodeStruct
{
public int f0;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string inlineString;
}
[DllImport("*", CallingConvention = CallingConvention.StdCall)]
static extern bool InlineArrayTest(ref InlineArrayStruct ias, ref InlineUnicodeStruct ius);
public static int Main(string[] args)
{
TestBlittableType();
@@ -167,7 +256,10 @@ namespace PInvokeTests
Console.WriteLine("Testing marshalling blittable struct arrays");
Foo[] arr_foo = new Foo[ArraySize];
Foo[] arr_foo = null;
ThrowIfNotEquals(true, IsNULL(arr_foo), "Blittable array null check failed");
arr_foo = new Foo[ArraySize];
for (int i = 0; i < ArraySize; i++)
{
arr_foo[i].a = i;
@@ -175,6 +267,16 @@ namespace PInvokeTests
}
ThrowIfNotEquals(0, CheckIncremental_Foo(arr_foo, ArraySize), "Array marshalling failed");
char[] a = "Hello World".ToCharArray();
ThrowIfNotEquals(true, VerifyAnsiCharArrayIn(a), "Ansi Char Array In failed");
char[] b = new char[12];
ThrowIfNotEquals(true, VerifyAnsiCharArrayOut(b), "Ansi Char Array Out failed");
ThrowIfNotEquals("Hello World!", new String(b), "Ansi Char Array Out failed2");
char[] c = null;
ThrowIfNotEquals(true, IsNULL(c), "AnsiChar Array null check failed");
}
private static void TestByRef()
@@ -200,15 +302,66 @@ namespace PInvokeTests
Console.WriteLine("Testing marshalling string");
ThrowIfNotEquals(1, VerifyAnsiString("Hello World"), "Ansi String marshalling failed.");
ThrowIfNotEquals(1, VerifyUnicodeString("Hello World"), "Unicode String marshalling failed.");
string s;
ThrowIfNotEquals(1, VerifyAnsiStringOut(out s), "Out Ansi String marshalling failed");
ThrowIfNotEquals("Hello World", s, "Out Ansi String marshalling failed");
VerifyAnsiStringInRef(ref s);
ThrowIfNotEquals("Hello World", s, "In Ref ansi String marshalling failed");
VerifyAnsiStringRef(ref s);
ThrowIfNotEquals("Hello World!", s, "Ref ansi String marshalling failed");
ThrowIfNotEquals(1, VerifyUnicodeStringOut(out s), "Out Unicode String marshalling failed");
ThrowIfNotEquals("Hello World", s, "Out Unicode String marshalling failed");
VerifyUnicodeStringInRef(ref s);
ThrowIfNotEquals("Hello World", s, "In Ref Unicode String marshalling failed");
VerifyUnicodeStringRef(ref s);
ThrowIfNotEquals("Hello World!", s, "Ref Unicode String marshalling failed");
string ss = null;
ThrowIfNotEquals(true, IsNULL(ss), "Ansi String null check failed");
}
private static void TestStringBuilder()
{
Console.WriteLine("Testing marshalling string builder");
StringBuilder sb = new StringBuilder(16);
VerifyStringBuilder(sb);
bool result = (sb.ToString() == "Hello World");
ThrowIfNotEquals(true, result, "Unicode String builder marshalling failed.");
StringBuilder sb = new StringBuilder("Hello World");
ThrowIfNotEquals(1, VerifyUnicodeStringBuilder(sb), "Unicode StringBuilder marshalling failed");
ThrowIfNotEquals("HELLO WORLD", sb.ToString(), "Unicode StringBuilder marshalling failed.");
StringBuilder sb1 = null;
// for null stringbuilder it should return -1
ThrowIfNotEquals(-1, VerifyUnicodeStringBuilder(sb1), "Null unicode StringBuilder marshalling failed");
StringBuilder sb2 = new StringBuilder("Hello World");
ThrowIfNotEquals(1, VerifyUnicodeStringBuilderIn(sb2), "In unicode StringBuilder marshalling failed");
// Only [In] should change stringbuilder value
ThrowIfNotEquals("Hello World", sb2.ToString(), "In unicode StringBuilder marshalling failed");
StringBuilder sb3 = new StringBuilder();
ThrowIfNotEquals(1, VerifyUnicodeStringBuilderOut(sb3), "Out Unicode string marshalling failed");
ThrowIfNotEquals("Hello World", sb3.ToString(), "Out Unicode StringBuilder marshalling failed");
StringBuilder sb4 = new StringBuilder("Hello World");
ThrowIfNotEquals(1, VerifyAnsiStringBuilder(sb4), "Ansi StringBuilder marshalling failed");
ThrowIfNotEquals("HELLO WORLD", sb4.ToString(), "Ansi StringBuilder marshalling failed.");
StringBuilder sb5 = null;
// for null stringbuilder it should return -1
ThrowIfNotEquals(-1, VerifyAnsiStringBuilder(sb5), "Null Ansi StringBuilder marshalling failed");
StringBuilder sb6 = new StringBuilder("Hello World");
ThrowIfNotEquals(1, VerifyAnsiStringBuilderIn(sb6), "In unicode StringBuilder marshalling failed");
// Only [In] should change stringbuilder value
ThrowIfNotEquals("Hello World", sb6.ToString(), "In unicode StringBuilder marshalling failed");
StringBuilder sb7 = new StringBuilder();
ThrowIfNotEquals(1, VerifyAnsiStringBuilderOut(sb7), "Out Ansi string marshalling failed");
ThrowIfNotEquals("Hello World!", sb7.ToString(), "Out Ansi StringBuilder marshalling failed");
}
@@ -298,6 +451,13 @@ namespace PInvokeTests
Delegate_Int closed = new Delegate_Int((new ClosedDelegateCLass()).Sum);
ThrowIfNotEquals(true, ReversePInvoke_Int(closed), "Closed Delegate marshalling failed.");
Delegate_String ret = GetDelegate();
ThrowIfNotEquals(true, ret("Hello World!"), "Delegate as P/Invoke return failed");
Delegate_String d = new Delegate_String(new ClosedDelegateCLass().GetString);
ThrowIfNotEquals(true, Callback(ref d), "Delegate IN marshalling failed");
ThrowIfNotEquals(true, d("Hello World!"), "Delegate OUT marshalling failed");
Delegate_String ds = new Delegate_String((new ClosedDelegateCLass()).GetString);
ThrowIfNotEquals(true, ReversePInvoke_String(ds), "Delegate marshalling failed.");
}
@@ -326,6 +486,18 @@ namespace PInvokeTests
public String f3;
}
// A second struct with the same name but nested. Regression test against native types being mangled into
// the compiler-generated type and losing fully qualified type name information.
class NesterOfSequentialStruct
{
[StructLayout(LayoutKind.Sequential)]
public struct SequentialStruct
{
public float f1;
public int f2;
}
}
[StructLayout(LayoutKind.Explicit)]
public struct ExplicitStruct
{
@@ -366,6 +538,12 @@ namespace PInvokeTests
StructTest_ByOut(out ss2);
ThrowIfNotEquals(true, ss2.f0 == 1 && ss2.f1 == 1.0 && ss2.f2 == 1.0 && ss2.f3.Equals("0123456"), "Struct marshalling scenario3 failed.");
NesterOfSequentialStruct.SequentialStruct ss3 = new NesterOfSequentialStruct.SequentialStruct();
ss3.f1 = 10.0f;
ss3.f2 = 123;
ThrowIfNotEquals(true, StructTest_Sequential2(ss3), "Struct marshalling scenario1 failed.");
ExplicitStruct es = new ExplicitStruct();
es.f1 = 100;
es.f2 = 100.0f;
@@ -377,9 +555,50 @@ namespace PInvokeTests
ns.f2 = es;
ThrowIfNotEquals(true, StructTest_Nested(ns), "Struct marshalling scenario5 failed.");
// RhpThrowEx is not implemented in CPPCodeGen
SequentialStruct[] ssa = null;
ThrowIfNotEquals(true, IsNULL(ssa), "Non-blittable array null check failed");
ssa = new SequentialStruct[3];
for (int i = 0; i < 3; i++)
{
ssa[i].f1 = 0;
ssa[i].f1 = i;
ssa[i].f2 = i*i;
ssa[i].f3 = i.LowLevelToString();
}
ThrowIfNotEquals(true, StructTest_Array(ssa, ssa.Length), "Array of struct marshalling failed");
InlineArrayStruct ias = new InlineArrayStruct();
ias.inlineArray = new short[128];
for (short i = 0; i < 128; i++)
{
ias.inlineArray[i] = i;
}
ias.inlineString = "Hello";
InlineUnicodeStruct ius = new InlineUnicodeStruct();
ius.inlineString = "Hello World";
#if !CODEGEN_CPP
bool pass = false;
ThrowIfNotEquals(true, InlineArrayTest(ref ias, ref ius), "inline array marshalling failed");
bool pass = true;
for (short i = 0; i < 128; i++)
{
if (ias.inlineArray[i] != i + 1)
{
pass = false;
}
}
ThrowIfNotEquals(true, pass, "inline array marshalling failed");
ThrowIfNotEquals("Hello World", ias.inlineString, "Inline ByValTStr Ansi marshalling failed");
ThrowIfNotEquals("Hello World", ius.inlineString, "Inline ByValTStr Unicode marshalling failed");
// RhpThrowEx is not implemented in CPPCodeGen
pass = false;
AutoStruct autoStruct = new AutoStruct();
try
{
@@ -421,4 +640,35 @@ namespace PInvokeTests
}
} //end of SafeMemoryHandle class
public static class LowLevelExtensions
{
// Int32.ToString() calls into glob/loc garbage that hits CppCodegen limitations
public static string LowLevelToString(this int i)
{
char[] digits = new char[11];
int numDigits = 0;
if (i == int.MinValue)
return "-2147483648";
bool negative = i < 0;
if (negative)
i = -i;
do
{
digits[numDigits] = (char)('0' + (i % 10));
numDigits++;
i /= 10;
}
while (i != 0);
if (negative)
{
digits[numDigits] = '-';
numDigits++;
}
Array.Reverse(digits);
return new string(digits, digits.Length - numDigits, numDigits);
}
}
}

View File

@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef Windows_NT
#include <windows.h>
#define DLL_EXPORT extern "C" __declspec(dllexport)
@@ -17,6 +18,29 @@
#define __stdcall
#endif
#if (_MSC_VER >= 1400) // Check MSC version
#pragma warning(push)
#pragma warning(disable: 4996) // Disable deprecation
#endif
void* MemAlloc(long bytes)
{
#ifdef Windows_NT
return (unsigned char *)CoTaskMemAlloc(bytes);
#else
return (unsigned char *)malloc(bytes);
#endif
}
void MemFree(void *p)
{
#ifdef Windows_NT
CoTaskMemFree(p);
#else
free(p);
#endif
}
DLL_EXPORT int __stdcall Square(int intValue)
{
return intValue * intValue;
@@ -94,18 +118,24 @@ DLL_EXPORT bool __stdcall GetNextChar(short *value)
int CompareAnsiString(const char *val, const char * expected)
{
if (val == NULL)
return strcmp(val, expected) == 0 ? 1 : 0;
}
int CompareUnicodeString(const unsigned short *val, const unsigned short *expected)
{
if (val == NULL && expected == NULL)
return 1;
if (val == NULL || expected == NULL)
return 0;
const char *p = expected;
const char *q = val;
const unsigned short *p = val;
const unsigned short *q = expected;
while (*p && *q && *p == *q)
{
p++;
q++;
}
return *p == 0 && *q == 0;
}
@@ -117,6 +147,45 @@ DLL_EXPORT int __stdcall VerifyAnsiString(char *val)
return CompareAnsiString(val, "Hello World");
}
void CopyAnsiString(char *dst, char *src)
{
if (src == NULL || dst == NULL)
return;
char *p = dst, *q = src;
while (*q)
{
*p++ = *q++;
}
*p = '\0';
}
DLL_EXPORT int __stdcall VerifyAnsiStringOut(char **val)
{
if (val == NULL)
return 0;
*val = (char*)MemAlloc(sizeof(char) * 12);
CopyAnsiString(*val, "Hello World");
return 1;
}
DLL_EXPORT int __stdcall VerifyAnsiStringRef(char **val)
{
if (val == NULL)
return 0;
if (!CompareAnsiString(*val, "Hello World"))
{
MemFree(*val);
return 0;
}
*val = (char*)MemAlloc(sizeof(char) * 13);
CopyAnsiString(*val, "Hello World!");
return 1;
}
DLL_EXPORT int __stdcall VerifyAnsiStringArray(char **val)
{
if (val == NULL || *val == NULL)
@@ -155,25 +224,52 @@ DLL_EXPORT int __stdcall VerifyUnicodeString(unsigned short *val)
return 0;
unsigned short expected[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0};
unsigned short *p = expected;
unsigned short *q = val;
while (*p && *q && *p == *q)
{
p++;
q++;
}
return *p == 0 && *q == 0;
return CompareUnicodeString(val, expected);
}
DLL_EXPORT int __stdcall VerifyUnicodeStringOut(unsigned short **val)
{
if (val == NULL)
return 0;
unsigned short *p = (unsigned short *)MemAlloc(sizeof(unsigned short) * 12);
unsigned short expected[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
for (int i = 0; i < 12; i++)
p[i] = expected[i];
*val = p;
return 1;
}
DLL_EXPORT int __stdcall VerifyUnicodeStringRef(unsigned short **val)
{
if (val == NULL)
return 0;
unsigned short expected[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0};
unsigned short *p = expected;
unsigned short *q = *val;
if (!CompareUnicodeString(p, q))
return 0;
MemFree(*val);
p = (unsigned short*)MemAlloc(sizeof(unsigned short) * 13);
int i;
for (i = 0; i < 11; i++)
p[i] = expected[i];
p[i++] = '!';
p[i] = '\0';
*val = p;
return 1;
}
DLL_EXPORT bool __stdcall VerifySizeParamIndex(unsigned char ** arrByte, unsigned char *arrSize)
{
*arrSize = 10;
#ifdef Windows_NT
*arrByte = (unsigned char *)CoTaskMemAlloc(sizeof(unsigned char) * (*arrSize));
#else
*arrByte = (unsigned char *)malloc(sizeof(unsigned char) * (*arrSize));
#endif
*arrByte = (unsigned char *)MemAlloc(sizeof(unsigned char) * (*arrSize));
if (*arrByte == NULL)
return false;
@@ -228,22 +324,98 @@ DLL_EXPORT bool __stdcall ReversePInvoke_Int(int(__stdcall *fnPtr) (int, int, in
return fnPtr(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) == 55;
}
DLL_EXPORT bool __stdcall ReversePInvoke_String(bool(__stdcall *fnPtr) (char *))
typedef bool(__stdcall *StringFuncPtr) (char *);
DLL_EXPORT bool __stdcall ReversePInvoke_String(StringFuncPtr fnPtr)
{
char str[] = "Hello World";
return fnPtr(str);
}
DLL_EXPORT void __stdcall VerifyStringBuilder(unsigned short *val)
bool CheckString(char *str)
{
char str[] = "Hello World";
int i;
for (i = 0; str[i] != '\0'; i++)
val[i] = (unsigned short)str[i];
val[i] = 0;
return CompareAnsiString(str, "Hello World!") == 1;
}
DLL_EXPORT StringFuncPtr __stdcall GetDelegate()
{
return CheckString;
}
DLL_EXPORT bool __stdcall Callback(StringFuncPtr *fnPtr)
{
char str[] = "Hello World";
if ((*fnPtr)(str) == false)
return false;
*fnPtr = CheckString;
return true;
}
// returns
// -1 if val is null
// 1 if val is "Hello World"
// 0 otherwise
DLL_EXPORT int __stdcall VerifyUnicodeStringBuilder(unsigned short *val)
{
if (val == NULL)
return -1;
if (!VerifyUnicodeString(val))
return 0;
for (int i = 0; val[i] != '\0'; i++)
{
if ((char)val[i] >= 'a' && (char)val[i] <= 'z')
{
val[i] += 'A' - 'a';
}
}
return 1;
}
DLL_EXPORT int __stdcall VerifyUnicodeStringBuilderOut(unsigned short *val)
{
if (val == NULL)
return 0;
unsigned short src[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
for (int i = 0; i < 12; i++)
val[i] = src[i];
return 1;
}
DLL_EXPORT int __stdcall VerifyAnsiStringBuilderOut(char *val)
{
if (val == NULL)
return 0;
CopyAnsiString(val, "Hello World!");
return 1;
}
// returns
// -1 if val is null
// 1 if val is "Hello World"
// 0 otherwise
DLL_EXPORT int __stdcall VerifyAnsiStringBuilder(char *val)
{
if (val == NULL)
return -1;
if (!VerifyAnsiString(val))
return 0;
for (int i = 0; val[i] != '\0'; i++)
{
if (val[i] >= 'a' && val[i] <= 'z')
{
val[i] += 'A' - 'a';
}
}
return 1;
}
DLL_EXPORT int* __stdcall ReversePInvoke_Unused(void(__stdcall *fnPtr) (void))
{
return 0;
@@ -257,6 +429,12 @@ struct NativeSequentialStruct
char *str;
};
struct NativeSequentialStruct2
{
float a;
int b;
};
DLL_EXPORT bool __stdcall StructTest(NativeSequentialStruct nss)
{
if (nss.s != 100)
@@ -275,6 +453,17 @@ DLL_EXPORT bool __stdcall StructTest(NativeSequentialStruct nss)
return true;
}
DLL_EXPORT bool __stdcall StructTest_Sequential2(NativeSequentialStruct2 nss)
{
if (nss.a != 10.0)
return false;
if (nss.b != 123)
return false;
return true;
}
DLL_EXPORT void __stdcall StructTest_ByRef(NativeSequentialStruct *nss)
{
nss->a++;
@@ -296,11 +485,7 @@ DLL_EXPORT void __stdcall StructTest_ByOut(NativeSequentialStruct *nss)
int arrSize = 7;
char *p;
#ifdef Windows_NT
p = (char *)CoTaskMemAlloc(sizeof(char) * arrSize);
#else
p = (char *)malloc(sizeof(char) * arrSize);
#endif
p = (char *)MemAlloc(sizeof(char) * arrSize);
for (int i = 0; i < arrSize; i++)
{
@@ -310,6 +495,69 @@ DLL_EXPORT void __stdcall StructTest_ByOut(NativeSequentialStruct *nss)
nss->str = p;
}
DLL_EXPORT bool __stdcall StructTest_Array(NativeSequentialStruct *nss, int length)
{
if (nss == NULL)
return false;
char expected[16];
for (int i = 0; i < 3; i++)
{
if (nss[i].s != 0)
return false;
if (nss[i].a != i)
return false;
if (nss[i].b != i*i)
return false;
sprintf(expected, "%d", i);
if (CompareAnsiString(expected, nss[i].str) == 0)
return false;
}
return true;
}
typedef struct {
int a;
int b;
int c;
short inlineArray[128];
char inlineString[11];
} inlineStruct;
typedef struct {
int a;
unsigned short inlineString[11];
} inlineUnicodeStruct;
DLL_EXPORT bool __stdcall InlineArrayTest(inlineStruct* p, inlineUnicodeStruct *q)
{
for (short i = 0; i < 128; i++)
{
if (p->inlineArray[i] != i)
return false;
p->inlineArray[i] = i + 1;
}
if (CompareAnsiString(p->inlineString, "Hello") != 1)
return false;
if (!VerifyUnicodeString(q->inlineString))
return false;
q->inlineString[5] = p->inlineString[5] = ' ';
q->inlineString[6] = p->inlineString[6] = 'W';
q->inlineString[7] = p->inlineString[7] = 'o';
q->inlineString[8] = p->inlineString[8] = 'r';
q->inlineString[9] = p->inlineString[9] = 'l';
q->inlineString[10] = p->inlineString[10] = 'd';
return true;
}
struct NativeExplicitStruct
{
@@ -349,3 +597,25 @@ DLL_EXPORT bool __stdcall StructTest_Nested(NativeNestedStruct nns)
return StructTest_Explicit(nns.nes);
}
DLL_EXPORT bool __stdcall VerifyAnsiCharArrayIn(char *a)
{
return CompareAnsiString(a, "Hello World") == 1;
}
DLL_EXPORT bool __stdcall VerifyAnsiCharArrayOut(char *a)
{
if (a == NULL)
return false;
CopyAnsiString(a, "Hello World!");
return true;
}
DLL_EXPORT bool __stdcall IsNULL(void *a)
{
return a == NULL;
}
#if (_MSC_VER >= 1400) // Check MSC version
#pragma warning(pop) // Renable previous depreciations
#endif

View File

@@ -0,0 +1,12 @@
@echo off
setlocal
"%1\%2"
set ErrorCode=%ERRORLEVEL%
IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
class PreInitializedAttribute: Attribute
{
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
class InitDataBlobAttribute: Attribute
{
public InitDataBlobAttribute(Type type, string fieldName)
{
}
}
}
class Details
{
private static IntPtr PreInitializedField_DataBlob = IntPtr.Zero;
}
public class PreInitDataTest
{
static int[] StaticIntArrayField = new int[] { 5, 6, 7, 8 };
[System.Runtime.CompilerServices.PreInitialized]
[System.Runtime.CompilerServices.InitDataBlob(typeof(Details), "PreInitializedField_DataBlob")]
static int[] PreInitializedField = new int[] { 1, 2, 3, 4 };
static string StaticStringField = "ABCDE";
const int Pass = 100;
const int Fail = -1;
public static int Main(string[] args)
{
int result = Pass;
if (!TestPreInitData())
{
Console.WriteLine("Failed");
result = Fail;
}
// Make sure PreInitializedField works with other statics
if (!TestOtherStatics())
{
Console.WriteLine("Failed");
result = Fail;
}
return result;
}
static bool TestPreInitData()
{
Console.WriteLine("Testing preinitialized array...");
for (int i = 0; i < PreInitializedField.Length; ++i)
{
if (PreInitializedField[i] != i + 1)
return false;
}
return true;
}
static bool TestOtherStatics()
{
Console.WriteLine("Testing other statics work well with preinitialized data in the same type...");
for (int i = 0; i < StaticIntArrayField.Length; ++i)
{
if (StaticIntArrayField[i] != i + 5)
return false;
}
if (StaticStringField != "ABCDE")
return false;
return true;
}
}

View File

@@ -0,0 +1,347 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly PreInitData
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module PreInitData.exe
// MVID: {916169DC-051D-4529-A01D-E629C1FB5BFB}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x001E0000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit Details
extends [mscorlib]System.Object
{
.class explicit ansi sealed nested private '__PreInitData__Size=16'
extends [mscorlib]System.ValueType
{
.pack 1
.size 16
} // end of class '__PreInitData__Size=16'
.field private static initonly valuetype Details/'__PreInitData__Size=16' PreInitializedField_DataBlob at I_00002A28
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Details::.ctor
} // end of class Details
.class public auto ansi beforefieldinit PreInitDataTest
extends [mscorlib]System.Object
{
.field private static int32[] StaticIntArrayField
.field private static int32[] PreInitializedField
.custom instance void System.Runtime.CompilerServices.PreInitializedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void System.Runtime.CompilerServices.InitDataBlobAttribute::.ctor(class [mscorlib]System.Type,
string) = ( 01 00 07 44 65 74 61 69 6C 73 1C 50 72 65 49 6E // ...Details.PreIn
69 74 69 61 6C 69 7A 65 64 46 69 65 6C 64 5F 44 // itializedField_D
61 74 61 42 6C 6F 62 00 00 ) // ataBlob..
.field private static string StaticStringField
.field private static literal int32 Pass = int32(0x00000064)
.field private static literal int32 Fail = int32(0xFFFFFFFF)
.method public hidebysig static int32 Main(string[] args) cil managed
{
.entrypoint
// Code size 64 (0x40)
.maxstack 2
.locals init (int32 V_0,
bool V_1,
bool V_2,
int32 V_3)
IL_0000: nop
IL_0001: ldc.i4.s 100
IL_0003: stloc.0
IL_0004: call bool PreInitDataTest::TestPreInitData()
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: brfalse.s IL_001f
IL_0010: nop
IL_0011: ldstr "Failed"
IL_0016: call void [mscorlib]System.Console::WriteLine(string)
IL_001b: nop
IL_001c: ldc.i4.m1
IL_001d: stloc.0
IL_001e: nop
IL_001f: call bool PreInitDataTest::TestOtherStatics()
IL_0024: ldc.i4.0
IL_0025: ceq
IL_0027: stloc.2
IL_0028: ldloc.2
IL_0029: brfalse.s IL_003a
IL_002b: nop
IL_002c: ldstr "Failed"
IL_0031: call void [mscorlib]System.Console::WriteLine(string)
IL_0036: nop
IL_0037: ldc.i4.m1
IL_0038: stloc.0
IL_0039: nop
IL_003a: ldloc.0
IL_003b: stloc.3
IL_003c: br.s IL_003e
IL_003e: ldloc.3
IL_003f: ret
} // end of method PreInitDataTest::Main
.method private hidebysig static bool TestPreInitData() cil managed
{
// Code size 65 (0x41)
.maxstack 3
.locals init (int32 V_0,
bool V_1,
bool V_2,
bool V_3)
IL_0000: nop
IL_0001: ldstr "Testing preinitialized array..."
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldc.i4.0
IL_000d: stloc.0
IL_000e: br.s IL_002d
IL_0010: nop
IL_0011: ldsfld int32[] PreInitDataTest::PreInitializedField
IL_0016: ldloc.0
IL_0017: ldelem.i4
IL_0018: ldloc.0
IL_0019: ldc.i4.1
IL_001a: add
IL_001b: ceq
IL_001d: ldc.i4.0
IL_001e: ceq
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: brfalse.s IL_0028
IL_0024: ldc.i4.0
IL_0025: stloc.2
IL_0026: br.s IL_003f
IL_0028: nop
IL_0029: ldloc.0
IL_002a: ldc.i4.1
IL_002b: add
IL_002c: stloc.0
IL_002d: ldloc.0
IL_002e: ldsfld int32[] PreInitDataTest::PreInitializedField
IL_0033: ldlen
IL_0034: conv.i4
IL_0035: clt
IL_0037: stloc.3
IL_0038: ldloc.3
IL_0039: brtrue.s IL_0010
IL_003b: ldc.i4.1
IL_003c: stloc.2
IL_003d: br.s IL_003f
IL_003f: ldloc.2
IL_0040: ret
} // end of method PreInitDataTest::TestPreInitData
.method private hidebysig static bool TestOtherStatics() cil managed
{
// Code size 90 (0x5a)
.maxstack 3
.locals init (int32 V_0,
bool V_1,
bool V_2,
bool V_3,
bool V_4)
IL_0000: nop
IL_0001: ldstr "Testing other statics work well with preinitialize"
+ "d data in the same type..."
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldc.i4.0
IL_000d: stloc.0
IL_000e: br.s IL_002d
IL_0010: nop
IL_0011: ldsfld int32[] PreInitDataTest::StaticIntArrayField
IL_0016: ldloc.0
IL_0017: ldelem.i4
IL_0018: ldloc.0
IL_0019: ldc.i4.5
IL_001a: add
IL_001b: ceq
IL_001d: ldc.i4.0
IL_001e: ceq
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: brfalse.s IL_0028
IL_0024: ldc.i4.0
IL_0025: stloc.2
IL_0026: br.s IL_0058
IL_0028: nop
IL_0029: ldloc.0
IL_002a: ldc.i4.1
IL_002b: add
IL_002c: stloc.0
IL_002d: ldloc.0
IL_002e: ldsfld int32[] PreInitDataTest::StaticIntArrayField
IL_0033: ldlen
IL_0034: conv.i4
IL_0035: clt
IL_0037: stloc.3
IL_0038: ldloc.3
IL_0039: brtrue.s IL_0010
IL_003b: ldsfld string PreInitDataTest::StaticStringField
IL_0040: ldstr "ABCDE"
IL_0045: call bool [mscorlib]System.String::op_Inequality(string,
string)
IL_004a: stloc.s V_4
IL_004c: ldloc.s V_4
IL_004e: brfalse.s IL_0054
IL_0050: ldc.i4.0
IL_0051: stloc.2
IL_0052: br.s IL_0058
IL_0054: ldc.i4.1
IL_0055: stloc.2
IL_0056: br.s IL_0058
IL_0058: ldloc.2
IL_0059: ret
} // end of method PreInitDataTest::TestOtherStatics
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method PreInitDataTest::.ctor
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 55 (0x37)
.maxstack 8
IL_0000: ldc.i4.4
IL_0001: newarr [mscorlib]System.Int32
IL_0006: dup
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=16' '<PrivateImplementationDetails>'::AB434F2ED820934995191E4C1A3C24AB41FF2E2C
IL_000c: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0011: stsfld int32[] PreInitDataTest::StaticIntArrayField
/*
IL_0016: ldc.i4.4
IL_0017: newarr [mscorlib]System.Int32
IL_001c: dup
IL_001d: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=16' '<PrivateImplementationDetails>'::'1456763F890A84558F99AFA687C36B9037697848'
IL_0022: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0027: stsfld int32[] PreInitDataTest::PreInitializedField
*/
IL_002c: ldstr "ABCDE"
IL_0031: stsfld string PreInitDataTest::StaticStringField
IL_0036: ret
} // end of method PreInitDataTest::.cctor
} // end of class PreInitDataTest
.class private auto ansi beforefieldinit System.Runtime.CompilerServices.PreInitializedAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 00 01 00 00 01 00 54 02 0D 41 6C 6C 6F 77 // ........T..Allow
4D 75 6C 74 69 70 6C 65 00 ) // Multiple.
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method PreInitializedAttribute::.ctor
} // end of class System.Runtime.CompilerServices.PreInitializedAttribute
.class private auto ansi beforefieldinit System.Runtime.CompilerServices.InitDataBlobAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 00 01 00 00 01 00 54 02 0D 41 6C 6C 6F 77 // ........T..Allow
4D 75 6C 74 69 70 6C 65 00 ) // Multiple.
.method public hidebysig specialname rtspecialname
instance void .ctor(class [mscorlib]System.Type 'type',
string fieldName) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ret
} // end of method InitDataBlobAttribute::.ctor
} // end of class System.Runtime.CompilerServices.InitDataBlobAttribute
.class private auto ansi sealed '<PrivateImplementationDetails>'
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.class explicit ansi sealed nested private '__StaticArrayInitTypeSize=16'
extends [mscorlib]System.ValueType
{
.pack 1
.size 16
} // end of class '__StaticArrayInitTypeSize=16'
.field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=16' AB434F2ED820934995191E4C1A3C24AB41FF2E2C at I_00002A38
} // end of class '<PrivateImplementationDetails>'
// =============================================================
.data cil I_00002A28 = bytearray (
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00)
.data cil I_00002A38 = bytearray (
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00)
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file PreInitData.res

View File

@@ -0,0 +1,7 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Include="*.il" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
</Project>

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
$1/$2
if [ $? == 100 ]; then
echo pass
exit 0
else
echo fail
exit 1
fi

View File

@@ -0,0 +1 @@
Skip this test for cpp codegen mode