Bug 17504 – Passing templated varargs to array varargs base class constructor segfaults

Status
RESOLVED
Resolution
INVALID
Severity
minor
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2017-06-14T16:12:00Z
Last change time
2017-06-14T17:13:07Z
Assigned to
nobody
Creator
nanayamae

Attachments

IDFilenameSummaryContent-TypeSize
1649varargs2.dReduction of the segfaultapplication/x-dsrc917

Comments

Comment #0 by nanayamae — 2017-06-14T16:12:50Z
Created attachment 1649 Reduction of the segfault I have a templated wrapper class (TC) that inherits from its template argument. The base class's (BC) constructor arguments are unknown, therefore the constructor of TC is templated with this(Args...)(MyType wrappedObj, Args args) { super(args); } and calls its base constructor using args. When the base constructor has varargs this(MyType[] objs...) { _objs = objs; } and TC's templated constructor is called using varargs auto tc = new TC(wrappedObj, obj1, obj2); // segfaults any attempt at accessing the objects in _objs by iterating (std.algorithm or foreach) segfaults (see attachment). Calling _objs[0] and accessing its members is ok. A workaround is passing in an array instead of varargs, therefore marked as minor. auto tc = new TC(wrappedObj, [obj1, obj2]); // ok The full code is in attachment. (Please forgive me if I mixed up a bit of terminology.)
Comment #1 by ag0aep6g — 2017-06-14T17:13:07Z
(In reply to Marco de Wild from comment #0) > this(MyType[] objs...) > { > _objs = objs; > } That's invalid code. The elements of `objs` are on the stack. `objs` is only valid during the constructor call. Later, `_objs` will contain garbage pointers. Dereferencing them then leads to a segfault. The spec says: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned" - https://dlang.org/spec/function.html#typesafe_variadic_functions I'm closing this as invalid. Just reopen if I'm missing something. However, the code should be rejected when you make the constructor `@safe`. It isn't. There's already an open issue for that: issue 5212.