From 54a0c41081f2bfd11054c3e7456b6ab4a915f28f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Aug 2023 09:58:28 +0200 Subject: Diagnose declarations of targets/prerequisites with abstract target types --- libbuild2/parser.cxx | 25 +++++++++++++++++++++++++ libbuild2/target.hxx | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'libbuild2') diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 5d77e2b..9ced841 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -172,6 +172,10 @@ namespace build2 tracer& tr) { auto r (p.scope_->find_target_type (n, o, loc)); + + if (r.first.factory == nullptr) + p.fail (loc) << "abstract target type " << r.first.name << "{}"; + return p.ctx->targets.insert ( r.first, // target type move (n.dir), @@ -192,6 +196,10 @@ namespace build2 tracer& tr) { auto r (p.scope_->find_target_type (n, o, loc)); + + if (r.first.factory == nullptr) + p.fail (loc) << "abstract target type " << r.first.name << "{}"; + return p.ctx->targets.find (r.first, // target type n.dir, o.dir, @@ -916,6 +924,8 @@ namespace build2 // Resolve target type. If none is specified, then it's file{}. // + // Note: abstract target type is ok here. + // const target_type* ttype (n.untyped () ? &file::static_type : scope_->find_target_type (n.type)); @@ -2765,6 +2775,9 @@ namespace build2 if (t == nullptr) fail (ploc) << "unknown target type " << n.type; + if (t->factory == nullptr) + fail (ploc) << "abstract target type " << t->name << "{}"; + // Current dir collapses to an empty one. // if (!n.dir.empty ()) @@ -4328,6 +4341,13 @@ namespace build2 if (bt == nullptr) fail (t) << "unknown target type " << bn; + // The derive_target_type() call below does not produce a non-abstract + // type if passed an abstract base. So we ban this for now (it's unclear + // why would someone want to do this). + // + if (bt->factory == nullptr) + fail (t) << "abstract base target type " << bt->name << "{}"; + // Note that the group{foo}<...> syntax is only recognized for group- // based targets and ad hoc buildscript recipes/rules only match group. // (We may want to relax this for member_hint in the future since its @@ -7521,6 +7541,8 @@ namespace build2 if (ttp == nullptr) ppat = pinc = false; + else if (ttp->factory == nullptr) + fail (loc) << "abstract target type " << ttp->name << "{}"; } } @@ -7682,6 +7704,9 @@ namespace build2 ? scope_->find_target_type (*tp) : nullptr); + if (ttp != nullptr && ttp->factory == nullptr) + fail (loc) << "abstract target type " << ttp->name << "{}"; + if (tp == nullptr || ttp != nullptr) { if (pmode == pattern_mode::detect) diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 79ec9fa..99383e7 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -2413,7 +2413,7 @@ namespace build2 // in the generic install rule. @@ This is still a TODO. // // Note that handling subsections with man1..9{} is easy, we - // simply specify the extension explicitly, e.g., man{foo.1p}. + // simply specify the extension explicitly, e.g., man1{foo.1p}. // class LIBBUILD2_SYMEXPORT man: public doc { -- cgit v1.1