Fix crash from --incompatible_enforce_config_setting_visibility
Reproducing requires https://github.com/bazelbuild/bazel/commit/a3a4cf8c486d1d27e72d9e595c9d718efb21071a and --incompatible_enforce_config_setting_visibility=1.
This is an obscure crash caused by a) building a test, b) with a select() on an alias, c) with --trim_test_configuration=1.
Details in commit.
For https://github.com/bazelbuild/bazel/issues/12932.
Fixes https://github.com/bazelbuild/bazel/issues/16446.
PiperOrigin-RevId: 480356600
Change-Id: I27227616dd2d1681b7769a29b73dac457f59d9b7
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 838f872..7cd33fa 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -1756,7 +1756,8 @@
// alias visibility, as is usual semantics. So two the following two edges are
// checked: 1: select() -> alias and 2: alias -> config_setting.
configSettingVisibilityPolicy == ConfigSettingVisibilityPolicy.DEFAULT_PUBLIC
- ? condition.fromConfiguredTarget(condition.getConfiguredTarget().getActual())
+ ? condition.fromConfiguredTargetNoCheck(
+ condition.getConfiguredTarget().getActual())
: condition);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetAndData.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetAndData.java
index 7171920..e7d8956 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetAndData.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetAndData.java
@@ -50,10 +50,22 @@
Target target,
BuildConfigurationValue configuration,
ImmutableList<String> transitionKeys) {
+ this(configuredTarget, target, configuration, transitionKeys, /*checkConsistency=*/ true);
+ }
+
+ private ConfiguredTargetAndData(
+ ConfiguredTarget configuredTarget,
+ Target target,
+ BuildConfigurationValue configuration,
+ ImmutableList<String> transitionKeys,
+ boolean checkConsistency) {
this.configuredTarget = configuredTarget;
this.target = target;
this.configuration = configuration;
this.transitionKeys = transitionKeys;
+ if (!checkConsistency) {
+ return;
+ }
Preconditions.checkState(
configuredTarget.getLabel().equals(target.getLabel()),
"Unable to construct ConfiguredTargetAndData:"
@@ -124,6 +136,19 @@
return new ConfiguredTargetAndData(maybeNew, target, configuration, transitionKeys);
}
+ /**
+ * Variation of {@link #fromConfiguredTarget} that doesn't check the new target has the same
+ * configuration as the original.
+ *
+ * <p>Intended for trimming (like {@code --trim_test_configuration}).
+ */
+ public ConfiguredTargetAndData fromConfiguredTargetNoCheck(ConfiguredTarget maybeNew) {
+ if (configuredTarget.equals(maybeNew)) {
+ return this;
+ }
+ return new ConfiguredTargetAndData(maybeNew, target, configuration, transitionKeys, false);
+ }
+
public Target getTarget() {
return target;
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java
index 8581035..4df31b5 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java
@@ -1028,10 +1028,11 @@
@Test
public void selectConcatenatedWithNonSupportingType() throws Exception {
writeConfigRules();
- scratch.file("foo/BUILD",
+ scratch.file(
+ "foo/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= 0 + select({",
+ " boolean_attr = 0 + select({",
" '//conditions:a': 0,",
" '//conditions:b': 1,",
" }))");
@@ -1476,7 +1477,7 @@
" actual = ':foo')",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" ':foo': 0,",
" 'alias_to_foo': 1,",
" }))");
@@ -1500,7 +1501,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1525,7 +1526,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1550,7 +1551,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1569,7 +1570,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1595,7 +1596,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1621,7 +1622,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1651,7 +1652,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo_alias': 0,",
" '//conditions:default': 1",
" }))");
@@ -1684,7 +1685,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo_alias': 0,",
" '//conditions:default': 1",
" }))");
@@ -1718,7 +1719,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo_alias': 0,",
" '//conditions:default': 1",
" }))");
@@ -1728,6 +1729,57 @@
}
@Test
+ public void defaultPublicVisibility_trimmedConfigsDontCrash() throws Exception {
+ // When enforcing config_setting visibility with
+ // --incompatible_config_setting_private_default_visibility=false, the alias
+ // ConfiguredTargetAndData clones itself with the ConfiguredTargetAndData of the config_setting
+ // it refers to. ConfiguredTargetAndData.fromConfiguredTarget has a safety check that both
+ // configs are the same. When the target with a select() is a test and --trim_test_configuration
+ // is on, the alias takes the parent's config (with TestOptions) but the config_setting has it
+ // stripped. This is a regression test that Blaze doesn't crash expecting those configs to be
+ // equal.
+ setPackageOptions(
+ "--incompatible_enforce_config_setting_visibility=true",
+ "--incompatible_config_setting_private_default_visibility=false");
+ useConfiguration("--trim_test_configuration=true");
+ scratch.file(
+ "c/defs.bzl",
+ "def _impl(ctx):",
+ " output = ctx.outputs.out",
+ " ctx.actions.write(output = output, content = 'hi', is_executable = True)",
+ " return [DefaultInfo(executable = output)]",
+ "",
+ "fake_test = rule(",
+ " attrs = {",
+ " 'msg': attr.string(),",
+ " },",
+ " test = True,",
+ " outputs = {'out': 'foo.out'},",
+ " implementation = _impl,",
+ ")");
+ scratch.file(
+ "c/BUILD",
+ "load(':defs.bzl', 'fake_test')",
+ "alias(",
+ " name = 'foo_alias',",
+ " actual = ':foo',",
+ ")",
+ "config_setting(",
+ " name = 'foo',",
+ " define_values = { 'foo': '1' },",
+ ")",
+ "fake_test(",
+ " name = 'foo_test',",
+ " msg = select({",
+ " ':foo_alias': 'hi',",
+ " '//conditions:default': 'there'",
+ " }))");
+ reporter.removeHandler(failFastHandler);
+ assertThat(getConfiguredTarget("//c:foo_test")).isNotNull();
+ assertNoEvents();
+ }
+
+ @Test
public void defaultVisibilityConfigSetting_defaultIsPrivate() throws Exception {
// Production builds default to private visibility, but BuildViewTestCase defaults to public.
setPackageOptions("--default_visibility=private",
@@ -1738,7 +1790,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1764,7 +1816,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");
@@ -1790,7 +1842,7 @@
"a/BUILD",
"rule_with_boolean_attr(",
" name = 'binary',",
- " boolean_attr= select({",
+ " boolean_attr = select({",
" '//c:foo': 0,",
" '//conditions:default': 1",
" }))");