Reactos
at master 244 lines 8.6 kB view raw
1/* 2 * Copyright 2016 Daniel Lehman (Esri) 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19#include <errno.h> 20#include <stdarg.h> 21#include <stdlib.h> 22#include <wchar.h> 23#include <stdio.h> 24 25#include <windef.h> 26#include <winbase.h> 27#include <verrsrc.h> 28#include <dbghelp.h> 29#include "wine/test.h" 30 31typedef unsigned char MSVCRT_bool; 32 33typedef struct { 34 const char *what; 35 MSVCRT_bool dofree; 36} __std_exception_data; 37 38typedef struct 39{ 40 char *name; 41 char mangled[32]; 42} type_info140; 43 44typedef struct _type_info_list 45{ 46 SLIST_ENTRY entry; 47 char name[1]; 48} type_info_list; 49 50static void* (CDECL *p_malloc)(size_t); 51static void (CDECL *p___std_exception_copy)(const __std_exception_data*, __std_exception_data*); 52static void (CDECL *p___std_exception_destroy)(__std_exception_data*); 53static int (CDECL *p___std_type_info_compare)(const type_info140*, const type_info140*); 54static const char* (CDECL *p___std_type_info_name)(type_info140*, SLIST_HEADER*); 55static void (CDECL *p___std_type_info_destroy_list)(SLIST_HEADER*); 56static size_t (CDECL *p___std_type_info_hash)(type_info140*); 57static char* (__cdecl *p___unDName)(char*,const char*,int,void*,void*,unsigned short int); 58 59static BOOL init(void) 60{ 61 HMODULE module; 62 63 module = LoadLibraryA("ucrtbase.dll"); 64 if (!module) 65 { 66 win_skip("ucrtbase.dll not installed\n"); 67 return FALSE; 68 } 69 70 p_malloc = (void*)GetProcAddress(module, "malloc"); 71 p___std_exception_copy = (void*)GetProcAddress(module, "__std_exception_copy"); 72 p___std_exception_destroy = (void*)GetProcAddress(module, "__std_exception_destroy"); 73 p___std_type_info_compare = (void*)GetProcAddress(module, "__std_type_info_compare"); 74 p___std_type_info_name = (void*)GetProcAddress(module, "__std_type_info_name"); 75 p___std_type_info_destroy_list = (void*)GetProcAddress(module, "__std_type_info_destroy_list"); 76 p___std_type_info_hash = (void*)GetProcAddress(module, "__std_type_info_hash"); 77 p___unDName = (void*)GetProcAddress(module, "__unDName"); 78 return TRUE; 79} 80 81static void test___std_exception(void) 82{ 83 __std_exception_data src; 84 __std_exception_data dst; 85 86 if (0) /* crash on Windows */ 87 { 88 p___std_exception_copy(NULL, &src); 89 p___std_exception_copy(&dst, NULL); 90 91 src.what = "invalid free"; 92 src.dofree = 1; 93 p___std_exception_destroy(&src); 94 p___std_exception_destroy(NULL); 95 } 96 97 src.what = "what"; 98 src.dofree = 0; 99 p___std_exception_copy(&src, &dst); 100 ok(dst.what == src.what, "expected what to be same, got src %p dst %p\n", src.what, dst.what); 101 ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); 102 103 src.dofree = 0x42; 104 p___std_exception_copy(&src, &dst); 105 ok(dst.what != src.what, "expected what to be different, got src %p dst %p\n", src.what, dst.what); 106 ok(dst.dofree == 1, "expected 1, got %d\n", dst.dofree); 107 108 p___std_exception_destroy(&dst); 109 ok(!dst.what, "expected NULL, got %p\n", dst.what); 110 ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); 111 112 src.what = NULL; 113 src.dofree = 0; 114 p___std_exception_copy(&src, &dst); 115 ok(!dst.what, "dst.what != NULL\n"); 116 ok(!dst.dofree, "dst.dofree != FALSE\n"); 117 118 src.what = NULL; 119 src.dofree = 1; 120 p___std_exception_copy(&src, &dst); 121 ok(!dst.what, "dst.what != NULL\n"); 122 ok(!dst.dofree, "dst.dofree != FALSE\n"); 123} 124 125static void test___std_type_info(void) 126{ 127 type_info140 ti1 = { NULL, ".?AVa@@" }; 128 type_info140 ti2 = { NULL, ".?AVb@@" }; 129 type_info140 ti3 = ti1; 130 SLIST_HEADER header; 131 type_info_list *elem; 132 const char *ret; 133 size_t hash1, hash2; 134 int eq; 135 136 137 InitializeSListHead(&header); 138 p___std_type_info_destroy_list(&header); 139 140 elem = p_malloc(sizeof(*elem)); 141 memset(elem, 0, sizeof(*elem)); 142 InterlockedPushEntrySList(&header, &elem->entry); 143 p___std_type_info_destroy_list(&header); 144 ok(!InterlockedPopEntrySList(&header), "list is not empty\n"); 145 146 ret = p___std_type_info_name(&ti1, &header); 147 ok(!strcmp(ret, "class a"), "__std_type_info_name(&ti1) = %s\n", ret); 148 ok(ti1.name == ret, "ti1.name = %p, ret = %p\n", ti1.name, ret); 149 150 p___std_type_info_destroy_list(&header); 151 ok(!InterlockedPopEntrySList(&header), "list is not empty\n"); 152 ok(ti1.name == ret, "ti1.name = %p, ret = %p\n", ti1.name, ret); 153 ti1.name = NULL; 154 155 eq = p___std_type_info_compare(&ti1, &ti1); 156 ok(eq == 0, "__std_type_info_compare(&ti1, &ti1) = %d\n", eq); 157 158 eq = p___std_type_info_compare(&ti1, &ti2); 159 ok(eq == -1, "__std_type_info_compare(&ti1, &ti2) = %d\n", eq); 160 161 eq = p___std_type_info_compare(&ti1, &ti3); 162 ok(eq == 0, "__std_type_info_compare(&ti1, &ti3) = %d\n", eq); 163 164 ti1.mangled[0] = 0; 165 ti1.mangled[1] = 0; 166 ti1.mangled[2] = 0; 167 hash1 = p___std_type_info_hash(&ti1); 168#ifdef _WIN64 169 ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); 170#else 171 ok(hash1 == 0x811c9dc5, "hash = %p\n", (void*)hash1); 172#endif 173 174 ti1.mangled[0] = 1; 175 hash2 = p___std_type_info_hash(&ti1); 176 ok(hash1 == hash2, "hash1 != hash2 (first char not ignored)\n"); 177 178 ti1.mangled[1] = 1; 179 hash1 = p___std_type_info_hash(&ti1); 180#ifdef _WIN64 181 ok(hash1 == 0xaf63bc4c29620a60, "hash = %p\n", (void*)hash1); 182#else 183 ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1); 184#endif 185 ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); 186 187 ti1.mangled[1] = 2; 188 hash2 = p___std_type_info_hash(&ti1); 189 ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); 190 191 hash1 = p___std_type_info_hash(&ti2); 192 ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); 193} 194 195static void test___unDName(void) 196{ 197 static struct {const char *in; const char *out; const char *broken; unsigned int flags;} und_tests[] = 198 { 199/* 0 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QAV0@@Z", 200 "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord &&)"}, 201/* 1 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QEAV0@@Z", 202 "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord && __ptr64)"}, 203/* 2 */ {"??__K_l@@YA?AUCC@@I@Z", "struct CC __cdecl operator \"\" _l(unsigned int)", 204 "??__K_l@@YA?AUCC@@I@Z" /* W10 1507 fails on this :-( */}, 205/* 3 */ {"?meth@Q@@QEGBA?AV1@XZ", 206 "public: class Q __cdecl Q::meth(void)const __ptr64& ", 207 "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */}, 208/* 4 */ {"?meth@Q@@QEHAA?AV1@XZ", 209 "public: class Q __cdecl Q::meth(void) __ptr64&& ", 210 "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */}, 211/* 5 */ {"?meth@Q@@QEGBA?AV1@XZ", 212 "public: class Q Q::meth(void)const & ", 213 "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */, 214 UNDNAME_NO_MS_KEYWORDS}, 215/* 6 */ {"?meth@Q@@QEHAA?AV1@XZ", 216 "public: class Q Q::meth(void)&& ", 217 "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */, 218 UNDNAME_NO_MS_KEYWORDS}, 219/* 7 */ {"?AU?$my_iter@H$0A@$$V@@", 220 "struct my_iter<int,0>", 221 NULL, 222 UNDNAME_NO_ARGUMENTS}, 223/* 8 */ {"??$foo@J_W$$T@bar@@YAJQB_W$$THQAUgod@@@Z", 224 "long __cdecl bar::foo<long,wchar_t,std::nullptr_t>(wchar_t const * const,std::nullptr_t,int,struct god * const)"}, 225 226 }; 227 unsigned i; 228 for (i = 0; i < ARRAY_SIZE(und_tests); i++) 229 { 230 char *name = p___unDName(0, und_tests[i].in, 0, malloc, free, und_tests[i].flags); 231 ok(!strcmp(name, und_tests[i].out) || 232 broken(und_tests[i].broken && !strcmp(und_tests[i].broken, name)), 233 "unDName returned %s for #%u\n", wine_dbgstr_a(name), i); 234 free(name); 235 } 236} 237 238START_TEST(cpp) 239{ 240 if (!init()) return; 241 test___std_exception(); 242 test___std_type_info(); 243 test___unDName(); 244}