From c67f2b63a9769d8ae3a07f78afd0c7dd2873563a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 23 Jan 2015 12:21:49 +0200 Subject: Diagnose lack of default constructor in pointed-to objects Lack of the default constructor will lead to uncompilable generated code. --- odb/processor.cxx | 22 +++++++++++++++++++++- odb/semantics/class.cxx | 8 +++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/odb/processor.cxx b/odb/processor.cxx index 291dcd3..a6f18e0 100644 --- a/odb/processor.cxx +++ b/odb/processor.cxx @@ -1313,6 +1313,9 @@ namespace } } + bool poly (polymorphic (*c)); + bool abst (abstract (*c)); + // Make sure the pointed-to class is complete. // if (!c->complete ()) @@ -1334,7 +1337,7 @@ namespace // Make sure the pointed-to class is not reuse-abstract. // - if (abstract (*c) && !polymorphic (*c)) + if (abst && !poly) { os << m.file () << ":" << m.line () << ":" << m.column () << ": " << "error: pointed-to class '" << class_fq_name (*c) << "' " @@ -1362,6 +1365,23 @@ namespace throw operation_failed (); } + // Make sure the pointed-to class has a default ctor. Since we will + // use database::load() in the generated code, lack of a default ctor + // will lead to uncompilable generated code. Poly-abstract is Ok. + // + if (!c->default_ctor () && !(abst && poly)) + { + os << m.file () << ":" << m.line () << ":" << m.column () << ": " + << "error: pointed-to class '" << class_fq_name (*c) << "' " + << "has no default constructor" << endl; + + os << c->file () << ":" << c->line () << ":" << c->column () << ": " + << "info: class '" << class_name (*c) << "' is defined here" + << endl; + + throw operation_failed (); + } + // See if this is the inverse side of a bidirectional relationship. // If so, then resolve the member and cache it in the context. // diff --git a/odb/semantics/class.cxx b/odb/semantics/class.cxx index 2d35a17..8c6877b 100644 --- a/odb/semantics/class.cxx +++ b/odb/semantics/class.cxx @@ -24,7 +24,13 @@ namespace semantics bool class_:: default_ctor () const { - return TYPE_HAS_DEFAULT_CONSTRUCTOR (tree_node ()); + tree t (tree_node ()); + + // TYPE_HAS_DEFAULT_CONSTRUCTOR() returns true if we have a + // deleted default ctor. locate_ctor(), on the other hand, + // returns NULL_TREE in this case. + // + return TYPE_HAS_DEFAULT_CONSTRUCTOR (t) && locate_ctor (t) != NULL_TREE; } bool class_:: -- cgit v1.1