From 16abe82cde1338e90f3c12cda540756a123b593e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 27 Oct 2017 05:12:28 +0200 Subject: [PATCH] LocationQuery: fix a segfault due to ill guided conversion path --- src/gui/interact/gen-node-location-query.hpp | 9 ++--- src/lib/diff/record.hpp | 35 +++++++++++------- wiki/thinkPad.ichthyo.mm | 37 ++++++++++++++++++++ 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/gui/interact/gen-node-location-query.hpp b/src/gui/interact/gen-node-location-query.hpp index 5c20c7183..5d3cbd6b4 100644 --- a/src/gui/interact/gen-node-location-query.hpp +++ b/src/gui/interact/gen-node-location-query.hpp @@ -71,7 +71,7 @@ //#include //#include //#include -//#include +#include //#include @@ -102,11 +102,12 @@ namespace interact { class GenNodeLocationQuery : public LocationQuery { - Rec const& tree_; + Rec tree_; public: - GenNodeLocationQuery(Rec const& backingStructure) - : tree_(backingStructure) + template + GenNodeLocationQuery(REC&& backingStructure) + : tree_(std::forward(backingStructure)) { } diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index 3cf404976..1158ec304 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -33,30 +33,31 @@ ** ** ## design decisions ** The Record type is shaped from its intended use: It serves to symbolically represent - ** \em objects in the "external tree description". Here, \em objects means objects for - ** real, i.e. with types, fields and an enclosed scope. But \em external means that we - ** do not work on these objects right here, we only represent them, for later referral, - ** \em symbolically. + ** _objects_ in the "external tree description". Here, "objects" means objects _for real_, + ** i.e. with types, fields and an enclosed scope. But \em external means that we do not work + ** on these objects right here, we only represent them, for later referral, _symbolically_. + ** + ** \par rationale + ** The underlying theme and motivation of this design is negative: we do not want + ** to build _yet another object system_. The object model of C++ is deemed adequate. ** ** This leads to the following decisions ** - the Record entity is itself an object and thus has an inner side, privately. ** The entrails of the Record can be reworked and tuned for performance ** - yet the Record has an external appearance, which makes it look flat and passive. ** This is to say, a Record has no visible functionality. - ** - the parts or \em realms within this symbolic representation are distinguished + ** - the parts or _realms_ within this symbolic representation are distinguished ** by convention solely ** ** * metadata is very limited and boils down to a type attribute known by name - ** * children (scope contents) can be recognised by \em not bearing a name + ** * children (scope contents) can be recognised by _not_ bearing a name ** ** Record entities are meant to be immutable. The proper way to alter a Record is - ** to apply a \link tree-diff.hpp diff \endlink. Yet for the \em implementation - ** of this diff handling, a Record::Mutator is provided, to allow controlled - ** partial re-building of a given data element. - ** - ** \par rationale - ** The underlying theme of this design is negative, dialectical: we do not want to - ** build yet another object system. The object model of C++ is deemed adequate. + ** to apply a [diff](\ref tree-diff.hpp). Yet for the _implementation_ of this + ** diff handling, a Record::Mutator is provided, to allow controlled partial + ** re-building of a given data element. Moreover, especially for Record, + ** this mutator can be used for a DSL-style compact notation of a complete + ** "object tree" -- a feature intended for writing unit tests. ** ** @remarks ** - the implementation is focused on the intended primary use case, @@ -279,6 +280,14 @@ namespace diff{ * copy-initialise (or convert) from the given Mutator instance. * @remarks need to code this explicitly, otherwise Record's * build-from sequence templated ctor would kick in. + * @warning beware of initialiser lists. Record has a dedicated + * ctor to accept an initialiser list of GenNode elements, + * and GenNode's ctor is deliberately _not explicit,_ to ease + * building argument lists wrapped in GenNodes. When writing + * initialisation expressions inline, the compiler might pick + * the conversion path through initialiser list, which means + * the contents of the Mutator end up wrapped into a GenNode, + * which in turn becomes the only child of the new Record. */ Record (Mutator const& mut) : Record((Record const&) mut) diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 0579ea183..3f6ec7113 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -4577,6 +4577,43 @@ + + + + + + + + + + + + + + + + + + + +

+ ...merke +

+

+ die Spezialbehandlung für const& gilt nur, wenn wir direkt auch diesen Typ nehmen. +

+

+ Im vorliegenden fall wird aber der conversion-Operator aufgerufen, um den Initializser zu erzeugen. +

+

+ Daher denkt der Compiler, er kann das Ursprungsobjekt jezt wergwerfen. +

+ + +
+ +
+