aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-10-02 16:06:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-10-02 16:06:56 +0200
commiteac23648aea3c1aa547dd4bb9872948df49a065a (patch)
tree554783055991e5a56147661f490fdcfc196b2fe7
parentf4c702b57d6626c86795fb45d41ed652116aab5f (diff)
Instantiate type of virtual data member with by-value accessor
-rw-r--r--odb/relational/processor.cxx49
1 files changed, 42 insertions, 7 deletions
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 8ab9a1f..68e8ab6 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -746,19 +746,54 @@ namespace relational
}
// Check that the member type is default-constructible if we
- // have a by value modifier.
+ // have a by value modifier.
//
if (k == "set" && ma.placeholder ())
{
- // Assume all other types are default-constructible.
- //
semantics::class_* c (dynamic_cast<semantics::class_*> (&utype (m)));
- if (c != 0 && !c->default_ctor ())
+ // Assume all other types are default-constructible.
+ //
+ if (c != 0)
{
- error (ma.loc) << "modifier expression requires member type "
- << "to be default-constructible" << endl;
- throw operation_failed ();
+ // If this type is a class template instantiation, then make
+ // sure it is instantiated. While types used in real members
+ // will be instantiated, this is not necessarily the case for
+ // virtual members. Without the instantiation we won't be able
+ // to detect whether the type has the default ctor.
+ //
+ // It would have been cleaner to do it in post_process_pragmas()
+ // but there we don't yet know whether we need the default ctor.
+ // And it is a good idea not to require instantiability unless
+ // we really need it.
+ //
+ tree type (c->tree_node ());
+
+ if (!COMPLETE_TYPE_P (type) &&
+ CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+ {
+ // Reset input location so that we get nice diagnostics in
+ // case of an error. Use the location of the virtual pragma.
+ //
+ location_t loc (m.get<location_t> ("virtual-location"));
+ input_location = loc;
+
+ if (instantiate_class_template (type) == error_mark_node ||
+ errorcount != 0 ||
+ !COMPLETE_TYPE_P (type))
+ {
+ error (loc) << "unable to instantiate virtual data member " <<
+ "type" << endl;
+ throw operation_failed ();
+ }
+ }
+
+ if (!c->default_ctor ())
+ {
+ error (ma.loc) << "modifier expression requires member type " <<
+ "to be default-constructible" << endl;
+ throw operation_failed ();
+ }
}
}
}