Skip to content

Commit 84d2814

Browse files
authored
Add ODR detection to WINRT_NO_MAKE_DETECTION (#735)
1 parent 3a95080 commit 84d2814

File tree

9 files changed

+67
-98
lines changed

9 files changed

+67
-98
lines changed

strings/base_implements.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
#if defined(_MSC_VER)
2+
#if defined(_DEBUG) && !defined(WINRT_NO_MAKE_DETECTION)
3+
#pragma detect_mismatch("C++/WinRT WINRT_NO_MAKE_DETECTION", "make detection enabled (DEBUG and !WINRT_NO_MAKE_DETECTION)")
4+
#else
5+
#pragma detect_mismatch("C++/WinRT WINRT_NO_MAKE_DETECTION", "make detection disabled (!DEBUG or WINRT_NO_MAKE_DETECTION)")
6+
#endif
7+
#endif
18

29
namespace winrt::impl
310
{

test/test/no_make_detection.cpp

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,10 @@
1-
// This test validates that defining WINRT_NO_MAKE_DETECTION actually
2-
// allows an implementation to be final and have a private destructor.
3-
// This is *not* recommended as there are no safeguards for direct and
4-
// invalid allocations, but is provided for compatibility.
5-
6-
#define WINRT_NO_MAKE_DETECTION
7-
#include "catch.hpp"
8-
#include "winrt/Windows.Foundation.h"
1+
#include "pch.h"
2+
#include "winrt/test_component.h"
93

104
using namespace winrt;
11-
using namespace Windows::Foundation;
12-
13-
namespace
14-
{
15-
struct Stringable final : implements<Stringable, IStringable>
16-
{
17-
hstring ToString()
18-
{
19-
return L"Stringable";
20-
}
21-
22-
inline static bool Destroyed{};
23-
24-
private:
25-
26-
~Stringable()
27-
{
28-
Destroyed = true;
29-
}
30-
};
31-
}
5+
using namespace test_component;
326

337
TEST_CASE("no_make_detection")
348
{
35-
{
36-
IStringable stringable{ (new Stringable())->get_abi<IStringable>(), take_ownership_from_abi };
37-
REQUIRE(!Stringable::Destroyed);
38-
stringable = nullptr;
39-
REQUIRE(Stringable::Destroyed);
40-
}
41-
{
42-
Stringable::Destroyed = false;
43-
IStringable stringable = make<Stringable>();
44-
REQUIRE(!Stringable::Destroyed);
45-
stringable = nullptr;
46-
REQUIRE(Stringable::Destroyed);
47-
}
9+
REQUIRE(test_component::Class::TestNoMakeDetection());
4810
}

test/test/test.vcxproj

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -410,16 +410,7 @@
410410
<ClCompile Include="names.cpp" />
411411
<ClCompile Include="noexcept.cpp" />
412412
<ClCompile Include="notify_awaiter.cpp" />
413-
<ClCompile Include="no_make_detection.cpp">
414-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
415-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
416-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
417-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
418-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
419-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
420-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
421-
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
422-
</ClCompile>
413+
<ClCompile Include="no_make_detection.cpp" />
423414
<ClCompile Include="numerics.cpp" />
424415
<ClCompile Include="out_params.cpp" />
425416
<ClCompile Include="out_params_abi.cpp" />

test/test_component/Class.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,48 @@ namespace winrt::test_component::implementation
471471
co_await args->wait_for_deferrals();
472472
co_return args->m_counter;
473473
}
474-
}
474+
475+
// This test validates that defining WINRT_NO_MAKE_DETECTION actually
476+
// allows an implementation to be final and have a private destructor.
477+
// This is *not* recommended as there are no safeguards for direct and
478+
// invalid allocations, but is provided for compatibility.
479+
480+
bool Class::TestNoMakeDetection()
481+
{
482+
static bool Destroyed{};
483+
484+
struct Stringable final : implements<Stringable, IStringable>
485+
{
486+
hstring ToString()
487+
{
488+
return L"Stringable";
489+
}
490+
491+
private:
492+
493+
~Stringable()
494+
{
495+
Destroyed = true;
496+
}
497+
};
498+
499+
bool pass = true;
500+
501+
{
502+
Destroyed = false;
503+
IStringable stringable{ (new Stringable())->get_abi<IStringable>(), take_ownership_from_abi };
504+
pass = pass && !Destroyed;
505+
506+
stringable = nullptr;
507+
pass = pass && Destroyed;
508+
}
509+
{
510+
Destroyed = false;
511+
IStringable stringable = make<Stringable>();
512+
pass = pass && !Destroyed;
513+
stringable = nullptr;
514+
pass = pass && Destroyed;
515+
}
516+
return pass;
517+
}
518+
}

test/test_component/Class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ namespace winrt::test_component::implementation
111111
event_token DeferrableEvent(Windows::Foundation::TypedEventHandler<test_component::Class, test_component::DeferrableEventArgs> const& handler);
112112
void DeferrableEvent(event_token const& token);
113113
Windows::Foundation::IAsyncOperation<int> RaiseDeferrableEventAsync();
114+
115+
static bool TestNoMakeDetection();
114116
private:
115117

116118
bool m_fail{};

test/test_component/pch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

33
#define WINRT_LEAN_AND_MEAN
4+
#define WINRT_NO_MAKE_DETECTION // for test in Class.cpp
45
#include <numeric>
56
#include <winrt/Windows.Foundation.h>

test/test_component/test_component.idl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ namespace test_component
148148

149149
event Windows.Foundation.TypedEventHandler<Class, DeferrableEventArgs> DeferrableEvent;
150150
Windows.Foundation.IAsyncOperation<Int32> RaiseDeferrableEventAsync();
151+
152+
static Boolean TestNoMakeDetection();
151153
}
152154

153155
namespace Structs
Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,10 @@
1-
// This test validates that defining WINRT_NO_MAKE_DETECTION actually
2-
// allows an implementation to be final and have a private destructor.
3-
// This is *not* recommended as there are no safeguards for direct and
4-
// invalid allocations, but is provided for compatibility.
5-
6-
#define WINRT_NO_MAKE_DETECTION
7-
#include "catch.hpp"
8-
#include "winrt/Windows.Foundation.h"
1+
#include "pch.h"
2+
#include "winrt/test_component.h"
93

104
using namespace winrt;
11-
using namespace Windows::Foundation;
12-
13-
namespace
14-
{
15-
struct Stringable final : implements<Stringable, IStringable>
16-
{
17-
hstring ToString()
18-
{
19-
return L"Stringable";
20-
}
21-
22-
inline static bool Destroyed{};
23-
24-
private:
25-
26-
~Stringable()
27-
{
28-
Destroyed = true;
29-
}
30-
};
31-
}
5+
using namespace test_component;
326

337
TEST_CASE("no_make_detection")
348
{
35-
{
36-
IStringable stringable{ (new Stringable())->get_abi<IStringable>(), take_ownership_from_abi };
37-
REQUIRE(!Stringable::Destroyed);
38-
stringable = nullptr;
39-
REQUIRE(Stringable::Destroyed);
40-
}
41-
{
42-
Stringable::Destroyed = false;
43-
IStringable stringable = make<Stringable>();
44-
REQUIRE(!Stringable::Destroyed);
45-
stringable = nullptr;
46-
REQUIRE(Stringable::Destroyed);
47-
}
9+
REQUIRE(test_component::Class::TestNoMakeDetection());
4810
}

test/test_win7/test_win7.vcxproj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,7 @@
358358
</ClCompile>
359359
<ClCompile Include="names.cpp" />
360360
<ClCompile Include="noexcept.cpp" />
361-
<ClCompile Include="no_make_detection.cpp">
362-
<PrecompiledHeader>NotUsing</PrecompiledHeader>
363-
</ClCompile>
361+
<ClCompile Include="no_make_detection.cpp" />
364362
<ClCompile Include="numerics.cpp" />
365363
<ClCompile Include="out_params.cpp" />
366364
<ClCompile Include="parent_includes.cpp" />

0 commit comments

Comments
 (0)