Skip to content

Commit f382299

Browse files
committed
Suppress non-virtual destructor warnings in the generated headers
The ABI interface structs, the delegate structs, and the produce<D, I> vtable adapters all have virtual functions and non-virtual destructors, which trips C4265/C5204 on MSVC and -Wnon-virtual-dtor on clang. Consumers building at high warning levels see hundreds of these (about 200 in a translation unit that exercises implements<>, delegates, events, and the collection helpers). None of those types is ever deleted. The only refcounted, heap-allocated type is root_implements, and it already has a virtual destructor. Everything below it is a non-owning subobject whose address is simply the COM interface pointer handed out for that interface, so the warning reports a delete that cannot occur. Emit a scoped push/disable/pop around the body of each generated header, using the same guarded style already used in base_delegate.h, base_implements.h, base_activation.h, and base_error.h. Because it is popped at the end of each header, consumer code outside these headers is unaffected.
1 parent 856eaff commit f382299

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

‎cppwinrt/code_writers.h‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,45 @@ namespace cppwinrt
8181
w.write(format);
8282
}
8383

84+
// The ABI interface structs, the delegate structs, and the produce<D, I> vtable adapters
85+
// all have virtual functions and non-virtual destructors, which trips C4265/C5204 on MSVC
86+
// and -Wnon-virtual-dtor on clang. None of those types is ever deleted. The only
87+
// refcounted, heap-allocated type is root_implements, and it already has a virtual
88+
// destructor; everything below it is a non-owning subobject whose address is simply the
89+
// COM interface pointer. The warning is therefore reporting a delete that cannot occur.
90+
// Scoped with push/pop so that consumer code outside these headers is unaffected.
91+
static void write_diagnostic_push(writer& w)
92+
{
93+
auto format = R"(#ifdef _MSC_VER
94+
#pragma warning(push)
95+
#pragma warning(disable: 4265) // class has virtual functions, but destructor is not virtual
96+
#pragma warning(disable: 5204) // class has virtual functions, but its trivial destructor is not virtual
97+
#endif // _MSC_VER
98+
#ifdef __clang__
99+
#pragma clang diagnostic push
100+
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
101+
#endif // __clang__
102+
)";
103+
104+
w.write(format);
105+
}
106+
107+
static void write_diagnostic_pop(writer& w)
108+
{
109+
auto format = R"(#ifdef __clang__
110+
#pragma clang diagnostic pop
111+
#endif // __clang__
112+
#ifdef _MSC_VER
113+
#pragma warning(pop)
114+
#endif // _MSC_VER
115+
)";
116+
117+
w.write(format);
118+
}
119+
84120
static void write_close_file_guard(writer& w)
85121
{
122+
write_diagnostic_pop(w);
86123
write_endif(w);
87124
}
88125

@@ -108,6 +145,7 @@ namespace cppwinrt
108145
)";
109146

110147
w.write(format, mangled_name, mangled_name);
148+
write_diagnostic_push(w);
111149
}
112150

113151
template<typename... Args>

0 commit comments

Comments
 (0)