Bug 20171 – [REG 2.086.0] null this in invariant after destructor called

Status
RESOLVED
Resolution
WORKSFORME
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-08-27T04:40:25Z
Last change time
2023-04-18T11:08:56Z
Keywords
contracts
Assigned to
No Owner
Creator
Eugene Wissner

Comments

Comment #0 by belka — 2019-08-27T04:40:25Z
This fascinating code segfaults: struct Range { } struct Array(T) { private int* data; invariant (this.data is null); ~this() { reserve(); } void reserve() { const byteSize = 0; } bool opEquals(R)(R that) const if (is(R == Range)) { assert(false); } } unittest { auto v = Array!int(); } dmd -unittest -main array.d ./array(_D4core7runtime18runModuleUnitTestsUZ19unittestSegvHandlerUNbiPSQCk3sys5posix6signal9siginfo_tPvZv+0x38)[0x4340fc] /lib64/libpthread.so.0(+0x113b0)[0x7ff3920d23b0] ./array(_D5array__T5ArrayTiZQj12__invariant3MxFNaNbNiNfZv+0x4)[0x42fbd0] ./array(_D5array__T5ArrayTiZQj11__invariantMxFNaNbNiNfZv+0x9)[0x42fc81] ./array(_D5array__T5ArrayTiZQj7reserveMFNaNbNiNfZv+0x1f)[0x42fc27] ./array(_D5array__T5ArrayTiZQj6__dtorMFNaNbNiNfZv+0x1a)[0x42fc06] ./array(_D5array17__unittest_L28_C1FZv+0x19)[0x42fbc9] ./array(_D5array9__modtestFZv+0x9)[0x42fc8d] ./array(_D4core7runtime18runModuleUnitTestsUZ14__foreachbody2MFPS6object10ModuleInfoZi+0x44)[0x43415c] ./array(_D6object10ModuleInfo7opApplyFMDFPSQBhQBdZiZ9__lambda2MFyPSQCfQCbZi+0x2f)[0x4330eb] ./array(_D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZ14__foreachbody2MFKSQCz19sections_elf_shared3DSOZi+0x5b)[0x43819b] ./array(_D2rt19sections_elf_shared3DSO7opApplyFMDFKSQBqQBqQyZiZi+0x45)[0x4386f5] ./array(_D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZi+0x22)[0x438122] ./array(_D6object10ModuleInfo7opApplyFMDFPSQBhQBdZiZi+0x22)[0x4330b6] ./array(runModuleUnitTests+0x13e)[0x433f2e] ./array(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv+0x25)[0x430751] ./array(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x24)[0x4306dc] ./array(_d_run_main+0x2cb)[0x430643] ./array(main+0x10)[0x42fca4] /lib64/libc.so.6(__libc_start_main+0xf0)[0x7ff3913d97d0] ./array(_start+0x29)[0x42fa79] Segmentation fault (core dumped)
Comment #1 by simen.kjaras — 2019-08-27T07:26:17Z
Reduced example: struct S(T) { invariant (&this != null); ~this() { fun(); } void fun() { int i; } void opEquals(T)(T t) if (false) { } } unittest { S!int a; } As the changed summary indicates, `this` is null in the invariant. It is not null in ~this() or in fun(). opEquals() is of course never instantiated, but it needs to be there - it needs to have a template constraint, and it needs to take at least one argument, which needs to have a name, and needs to be of the type in the template parameter list. The invariant is called after fun(), so fun() needs to be there. It can't be empty, but it obviously doesn't need to do anything sensible.
Comment #2 by razvan.nitu1305 — 2023-04-18T11:08:56Z
I cannot reproduce the segfault. Compiling and running both the original code snippet and the reduced one result in successful compilation and run.