Bug 19666 – Implicit cast from static array to its .ptr not properly rejected during CTFE

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-02-11T02:07:42Z
Last change time
2024-12-13T19:02:23Z
Keywords
CTFE, ice
Assigned to
No Owner
Creator
andy-hanson
Moved to GitHub: dmd#17897 →

Comments

Comment #0 by andy-hanson — 2019-02-11T02:07:42Z
``` struct StoreAny { enum size_t maxSize = (void*).sizeof; enum size_t maxAlign = (void*).alignof; align(maxAlign) ubyte[maxSize] store; @trusted this(T)(T value) { static assert(T.sizeof <= maxSize && T.alignof <= maxAlign); *(cast(T*) store) = value; } @trusted T as(T)() { return *(cast(T*) store); } } struct SomeStruct { int x; } enum StoreAny someEnum = StoreAny(SomeStruct()); void main() { } ``` Compiling this code causes the compiler to terminate with SIGILL. There is no error if I instantiate with a primitive, e.g. `StoreAny(0)`.
Comment #1 by b2.temp — 2019-03-03T12:27:44Z
This is actually an assertion failure during CTFE: --- ERROR: This is a compiler bug. Please report it via https://issues.dlang.org/enter_bug.cgi with, preferably, a reduced, reproducible example and the information below. DustMite (https://github.com/CyberShadow/DustMite/wiki) can help with the reduction. --- DMD v2.085.0-81-g4a73e58c1-dirty predefs DigitalMars Posix linux ELFv1 CRuntime_Glibc CppRuntime_Gcc LittleEndian D_Version2 all D_SIMD D_InlineAsm_X86_64 X86_64 D_LP64 D_PIC assert D_ModuleInfo D_Exceptions D_TypeInfo D_HardFloat binary dmd/generated/linux/debug/64/dmd version v2.085.0-81-g4a73e58c1-dirty config dmd.conf DFLAGS -I./../../../../../druntime/import -I./../../../../../phobos -L-L./../../../../../phobos/generated/linux/debug/64 -L--export-dynamic -fPIC --- core.exception.AssertError@dmd/ctfeexpr.d(1685): Assertion failure ---------------- ??:? _d_assertp [0x7bc0a8] dmd/ctfeexpr.d:1685 void dmd.ctfeexpr.assignInPlace(dmd.expression.Expression, dmd.expression.Expression) [0x56f0b8] dmd/dinterpret.d:4035 _ZN11Interpreter14assignToLvalueEP6BinExpP10ExpressionS3_ [0x58fd57] dmd/dinterpret.d:3916 void dmd.dinterpret.Interpreter.interpretAssignCommon(dmd.expression.BinExp, dmd.expression.UnionExp function(ref const(dmd.globals.Loc), dmd.mtype.Type, dmd.expression.Expression, dmd.expression.Expression)*, int) [0x58f6ce] dmd/dinterpret.d:4495 _ZN11Interpreter5visitEP9AssignExp [0x5917f4] dmd/expression.d:5718 _ZN9AssignExp6acceptEP7Visitor [0x5ee96d] dmd/dinterpret.d:6491 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.UnionExp*, dmd.expression.Expression, dmd.dinterpret.InterState*, dmd.dinterpret.CtfeGoal) [0x597767] dmd/dinterpret.d:1096 _ZN11Interpreter5visitEP12ExpStatement [0x587610] dmd/statement.d:738 _ZN12ExpStatement6acceptEP7Visitor [0x68e051] dmd/dinterpret.d:6523 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.UnionExp*, dmd.statement.Statement, dmd.dinterpret.InterState*) [0x597846] dmd/dinterpret.d:1114 _ZN11Interpreter5visitEP17CompoundStatement [0x5876d5] dmd/statement.d:935 _ZN17CompoundStatement6acceptEP7Visitor [0x68e8b1] dmd/dinterpret.d:6523 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.UnionExp*, dmd.statement.Statement, dmd.dinterpret.InterState*) [0x597846] dmd/dinterpret.d:1114 _ZN11Interpreter5visitEP17CompoundStatement [0x5876d5] dmd/statement.d:935 _ZN17CompoundStatement6acceptEP7Visitor [0x68e8b1] dmd/dinterpret.d:6523 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.UnionExp*, dmd.statement.Statement, dmd.dinterpret.InterState*) [0x597846] dmd/dinterpret.d:966 dmd.expression.Expression dmd.dinterpret.interpretFunction(dmd.expression.UnionExp*, dmd.func.FuncDeclaration, dmd.dinterpret.InterState*, dmd.root.array.Array!(dmd.expression.Expression).Array*, dmd.expression.Expression) [0x58721d] dmd/dinterpret.d:5035 _ZN11Interpreter5visitEP7CallExp [0x592cac] dmd/expression.d:4892 _ZN7CallExp6acceptEP7Visitor [0x5ecfe5] dmd/dinterpret.d:6491 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.UnionExp*, dmd.expression.Expression, dmd.dinterpret.InterState*, dmd.dinterpret.CtfeGoal) [0x597767] dmd/dinterpret.d:6501 dmd.expression.Expression dmd.dinterpret.interpret(dmd.expression.Expression, dmd.dinterpret.InterState*, dmd.dinterpret.CtfeGoal) [0x5977c1] dmd/dinterpret.d:87 dmd.expression.Expression dmd.dinterpret.ctfeInterpret(dmd.expression.Expression) [0x585001] dmd/expression.d:1548 _ZN10Expression13ctfeInterpretEv [0x5e4f34] dmd/initsem.d:393 dmd.init.Initializer dmd.initsem.initializerSemantic(dmd.init.Initializer, dmd.dscope.Scope*, dmd.mtype.Type, dmd.init.NeedInterpret).visitExp(dmd.init.ExpInitializer) [0x631552] dmd/initsem.d:523 _Z19initializerSemanticP11InitializerP5ScopeP4Type13NeedInterpret [0x62fee2] dmd/dsymbolsem.d:1274 _ZN22DsymbolSemanticVisitor5visitEP14VarDeclaration [0x5bb8f3] dmd/declaration.d:1640 _ZN14VarDeclaration6acceptEP7Visitor [0x5810c1] dmd/dsymbolsem.d:365 _Z15dsymbolSemanticP7DsymbolP5Scope [0x5b8b84] dmd/dsymbolsem.d:1979 void dmd.dsymbolsem.DsymbolSemanticVisitor.visit(dmd.dmodule.Module).__lambda2!(dmd.dsymbol.Dsymbol).__lambda2(dmd.dsymbol.Dsymbol) [0x5bdf97] dmd/dsymbol.d:97 void dmd.dsymbol.foreachDsymbol(dmd.root.array.Array!(dmd.dsymbol.Dsymbol).Array*, void delegate(dmd.dsymbol.Dsymbol)) [0x5b2f8f] dmd/dsymbolsem.d:1976 _ZN22DsymbolSemanticVisitor5visitEP6Module [0x5bdf23] dmd/dmodule.d:1290 _ZN6Module6acceptEP7Visitor [0x5a10ed] dmd/dsymbolsem.d:365 _Z15dsymbolSemanticP7DsymbolP5Scope [0x5b8b84] dmd/mars.d:560 int dmd.mars.tryMain(ulong, const(char)**, ref dmd.globals.Param) [0x65628e] dmd/mars.d:859 _Dmain [0x657838]
Comment #2 by b2.temp — 2019-03-03T12:38:41Z
reduced: --- struct StoreAny { ubyte[16] store; this(T)(T value) { *(cast(T*) store) = value; } } struct SomeStruct {} enum StoreAny someEnum = StoreAny(SomeStruct()); void main() { } --- but code is invalid anyway. I suspect that the intention was more *(cast(T*) &store) = value; which CTFE cant do anyway.
Comment #3 by b2.temp — 2023-10-05T13:30:08Z
my last comment is wrong, the problem is that implicit conv from static array to its .ptr is not implemented correctly in the CTFE engine. The expected error happens when doing the cast explicitly: ```d struct StoreAny { ubyte[16] store; this(T)(T value) { *(cast(T*) store.ptr) = value; } } struct SomeStruct {} enum StoreAny someEnum = StoreAny(SomeStruct()); ``` > a.d:4:20: Error: reinterpreting cast from `ubyte*` to `SomeStruct*` is not supported in CTFE
Comment #4 by robert.schadek — 2024-12-13T19:02:23Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17897 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB