aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-11-08 12:45:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-11-08 12:45:33 +0200
commitdbb7a5ffefefa1e6439464cac47ebfd90a913aa7 (patch)
treebec6ea433f5ae1cd7c7eaddd3f57fa82a6cb4960
parent0c2c473c9937a54562bbf767cc5450f6c03bcce6 (diff)
Fix bug in override logic for command line variable with project visibility
-rw-r--r--build2/scope.cxx16
-rw-r--r--build2/scope.hxx6
-rw-r--r--build2/scope.ixx12
3 files changed, 29 insertions, 5 deletions
diff --git a/build2/scope.cxx b/build2/scope.cxx
index b9dabe8..49263d4 100644
--- a/build2/scope.cxx
+++ b/build2/scope.cxx
@@ -225,9 +225,9 @@ namespace build2
const scope* s;
- // Return true if the override applies. Note that it expects vars and proj
- // to be not NULL; if there is nothing "more inner", then any override
- // will still be "visible".
+ // Return true if the override applies to a value from vars/proj. Note
+ // that it expects vars and proj to be not NULL; if there is nothing "more
+ // inner", then any override will still be "visible".
//
auto applies = [&s] (const variable* o,
const variable_map* vars,
@@ -246,9 +246,15 @@ namespace build2
}
case variable_visibility::project:
{
- // Does not apply if in a different project.
+ // Does not apply if in a subproject.
//
- if (proj != s->root_scope ())
+ // Note that before we used to require the same project but that
+ // missed values that are "visible" from the outer projects.
+ //
+ // If root scope is NULL, then we are looking at the global scope.
+ //
+ const scope* rs (s->root_scope ());
+ if (rs != nullptr && rs->sub_root (*proj))
return false;
break;
diff --git a/build2/scope.hxx b/build2/scope.hxx
index 770f320..7929bce 100644
--- a/build2/scope.hxx
+++ b/build2/scope.hxx
@@ -70,6 +70,12 @@ namespace build2
scope* weak_scope ();
const scope* weak_scope () const;
+ // Return true if the specified root scope is a sub-scope of this root
+ // scope. Note that both scopes must be root.
+ //
+ bool
+ sub_root (const scope&) const;
+
// Variables.
//
public:
diff --git a/build2/scope.ixx b/build2/scope.ixx
index 9a93e9d..ac71e82 100644
--- a/build2/scope.ixx
+++ b/build2/scope.ixx
@@ -39,4 +39,16 @@ namespace build2
for (; r->parent_->root_ != nullptr; r = r->parent_->root_) ;
return r;
}
+
+ inline bool scope::
+ sub_root (const scope& r) const
+ {
+ // Scan the parent root scope chain looking for this scope.
+ //
+ for (const scope* pr (&r); (pr = pr->parent_->root_) != nullptr; )
+ if (pr == this)
+ return true;
+
+ return false;
+ }
}