Fix bugzilla issue 24882 - COM class is allocated using GC not malloc

This commit is contained in:
Richard (Rikki) Andrew Cattermole 2024-11-26 17:09:50 +13:00 committed by The Dlang Bot
parent 8b1eb80d25
commit 6567f6f4a4
6 changed files with 35 additions and 1 deletions

View file

@ -0,0 +1,5 @@
New trait isCOMClass to detect if a type is a COM class
A COM class inherits from a possibly user defined interface called ``IUnknown``.
To detect this during compilation use the trait ``__traits(isCOMClass, Type)``.
Or for during runtime use the ``TypeInfo_Class`` flag.

View file

@ -8692,6 +8692,7 @@ struct Id final
static Identifier* isRef;
static Identifier* isOut;
static Identifier* isLazy;
static Identifier* isCOMClass;
static Identifier* hasMember;
static Identifier* identifier;
static Identifier* fullyQualifiedName;

View file

@ -482,6 +482,7 @@ immutable Msgtable[] msgtable =
{ "isRef" },
{ "isOut" },
{ "isLazy" },
{ "isCOMClass" },
{ "hasMember" },
{ "identifier" },
{ "fullyQualifiedName" },

View file

@ -693,6 +693,26 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return isDeclX(d => (d.storage_class & STC.lazy_) != 0);
}
if (e.ident == Id.isCOMClass)
{
if (dim != 1)
return dimError(1);
auto o = (*e.args)[0];
auto s = getDsymbol(o);
AggregateDeclaration agg;
if (!s || ((agg = s.isAggregateDeclaration()) is null))
{
error(e.loc, "argument to `__traits(isCOMClass, %s)` is not a declaration", o.toChars());
return ErrorExp.get();
}
if (ClassDeclaration cd = agg.isClassDeclaration())
return cd.com ? True() : False();
else
return False();
}
if (e.ident == Id.identifier)
{
// Get identifier for symbol as a string literal

View file

@ -12,6 +12,10 @@ extern (Windows):
{printf(`comobject\n`);
}
}
// https://issues.dlang.org/show_bug.cgi?id=24882
static assert(__traits(isCOMClass, ComObject));
interface IDataObject: IUnknown
{
extern(Windows):

View file

@ -2739,8 +2739,11 @@ if (is(T == class))
auto init = __traits(initSymbol, T);
void* p;
static if (__traits(getLinkage, T) == "Windows")
static if (__traits(isCOMClass, T))
{
// If this is a COM class we allocate it using malloc.
// This allows the reference counting to outlive the reference known about by the GC.
p = pureMalloc(init.length);
if (!p)
onOutOfMemoryError();