Fixes the invariant not called on extern(C++) classes issue (#20981)

This commit is contained in:
Abul Hossain Khan 2025-03-13 16:06:45 +05:30 committed by GitHub
parent c5ba78dc34
commit 35f1146a1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 5 deletions

View file

@ -820,15 +820,13 @@ extern (C++) class FuncDeclaration : Declaration
bool addPreInvariant()
{
auto ad = isThis();
ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;
return (ad && !(cd && cd.isCPPclass()) && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
return (ad && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
}
bool addPostInvariant()
{
auto ad = isThis();
ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;
return (ad && !(cd && cd.isCPPclass()) && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
return (ad && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
}
override const(char)* kind() const

View file

@ -228,8 +228,52 @@ void test16384()
assert(s == "needs to be thrown2");
}
/***************************************************/
// Fix: https://github.com/dlang/dmd/issues/20924 (invariant not called on extern(C++) classes)
extern(C++) class C
{
invariant { assert(0); }
void f() {}
}
extern(D) class D
{
invariant { assert(0); }
void f() {}
}
void test20924()
{
import core.exception : AssertError;
// Test extern(C++) class invariant
try
{
auto c = new C();
c.f(); // Trigger invariant
assert(false, "Failed: invariant in extern(C++) class not checked");
}
catch (AssertError e)
{
// Expected behavior - invariant was checked
return;
}
assert(0, "Invariant in extern(C++) class was not checked");
// Test extern(D) class invariant
try
{
auto d = new D();
d.f(); // Trigger invariant
assert(false, "Failed: invariant in extern(D) class not checked");
}
catch (AssertError e)
{
// Expected behavior - invariant was checked
return;
}
assert(0, "Invariant in extern(D) class was not checked");
}
void main()
{
@ -238,4 +282,5 @@ void main()
test16384();
test13113();
test13147();
test20924();
}