CTFE bug causes null check to pass on null pointers (Issue 7602)

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Mar 19 14:14:38 PDT 2012


On Mon, Mar 19, 2012 at 09:46:04PM +0100, Don wrote:
> On 19.03.2012 18:25, H. S. Teoh wrote:
[...]
> >The main idea is to require a minimal number of lowerings from the
> >compiler (effectively nothing more than syntactic sugar such as V[K]
> >and AA literal syntax), and everything else will be done via existing
> >operator overloading and templating mechanisms. Ideally, CTFE will
> >"just work" with this implementation instead of requiring
> >druntime-specific hacks in the compiler (but I'm not sure whether
> >this will work, since it has to do memory allocations -- does CTFE
> >support that?).
> 
> Yes, CTFE supports 'new'. The big issue for the runtime is supporting
> AA literals. CTFE needs to be able to take the output of the runtime
> functions, and pass it as an AA literal to the rest of the compiler.

I've thought about supporting literals. Currently what I have in mind is
to build the AA in CTFE, then use mixins to explicitly create Slot
structs and link them all up into an Impl struct. The address of the
Impl struct (that contains the array of Slot*) is then readable at
compile-time, so it can be assigned to const AA variables, .dup'd into
mutable AA variables, etc.

This only works for literals that only have compile-time known contents,
of course. Things like:

	int x;
	int[string] aa = [ "abc": x ];

won't work with this scheme.  To support literals that reference
variables, some kind of runtime mechanism would be needed, perhaps
something similar to the current implementation where the compiler
passes an array of keys and an array of values to an AA factory
function.


[...]
> >>I do not understand why it still part of the compiler after we
> >>agreed to roll back to the D1 version.
> >
> >I'm late to the game; how was the D1 version implemented?
> 
> It was just extern(C) library functions.
> 
> The D2 version is exactly the same thing (all of the D1 functions
> still exist in D2), except that it has an AssociativeArray!(Key,
> Value) wrapper around the extern(C) functions.
> Which sounds like a trivial intermediate step to a full library
> implementation, but it isn't.

Yeah, this "wrapper" is the source of a good number of issues currently
on the bugtracker. It's also extremely ugly (the Range interface, for
example, is essentially a copy-n-paste of the structs in aaA.d).


> - it's a template, so it needs to be instantiated. What happens if
> it hasn't been instantiated yet?
> - what happens when AssociativeArray isn't a struct template?
> - what happens if there's an error while instantiating it?
> - what happens when all the functions are inlined away, and you're
> left with just void* pointers?
> - what happens when you something of type V[K] interacting with
> something of type AssociativeArray!(K, V)? This happens in things
> like template constraints, is() expressions, etc.
> - how is CTFE supposed to deal with this ruddy thing, that's fully
> of nasty casts to void *, and which may yet create AA literals
> themselves?
> - how are you supposed to get sensible error messages out of this beast?

The source of most of these problems is the schizophrenic split between
aaA.d and struct AssociativeArray. It has to be one or the other. There
can be no intermediate. The compiler needs to treat V[K] as an alias for
AssociativeArray!(K,V) (or vice versa, but regardless, the two must be
*identical* in all respects). Having two different things for them (such
as aaA.d returning void* and AssociativeArray!(K,V) being a struct
wrapping a void*) only leads to pain and disaster.


> The answer to these questions is, hundreds of hours work, and the
> biggest implementation disaster in D's history. There can be no
> 'intermediate step'. The syntax sugar should be added last, not first.

Agreed.


T

-- 
"Computer Science is no more about computers than astronomy is about telescopes." -- E.W. Dijkstra


More information about the Digitalmars-d mailing list