Add checks for list parameters of cc_common.create_cc_toolchain_config_info() to prevent bazel crashing when a struct is expected but something else is passed instead.
Fixes #8435
RELNOTES: None.
PiperOrigin-RevId: 253212600
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 49970a7..ba16c83 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -653,6 +653,7 @@
ImmutableList.Builder<Feature> featureBuilder = ImmutableList.builder();
for (Object feature : features) {
+ checkRightSkylarkInfoProvider(feature, "features", "FeatureInfo");
featureBuilder.add(featureFromSkylark((SkylarkInfo) feature));
}
ImmutableList<Feature> featureList = featureBuilder.build();
@@ -668,6 +669,7 @@
ImmutableList.Builder<ActionConfig> actionConfigBuilder = ImmutableList.builder();
for (Object actionConfig : actionConfigs) {
+ checkRightSkylarkInfoProvider(actionConfig, "action_configs", "ActionConfigInfo");
actionConfigBuilder.add(actionConfigFromSkylark((SkylarkInfo) actionConfig));
}
ImmutableList<ActionConfig> actionConfigList = actionConfigBuilder.build();
@@ -678,6 +680,8 @@
ImmutableList.Builder<ArtifactNamePattern> artifactNamePatternBuilder = ImmutableList.builder();
for (Object artifactNamePattern : artifactNamePatterns) {
+ checkRightSkylarkInfoProvider(
+ artifactNamePattern, "artifact_name_patterns", "ArtifactNamePatternInfo");
artifactNamePatternBuilder.add(
artifactNamePatternFromSkylark((SkylarkInfo) artifactNamePattern));
}
@@ -697,6 +701,7 @@
// Pairs (toolName, toolPath)
ImmutableList.Builder<Pair<String, String>> toolPathPairs = ImmutableList.builder();
for (Object toolPath : toolPaths) {
+ checkRightSkylarkInfoProvider(toolPath, "tool_paths", "ToolPathInfo");
Pair<String, String> toolPathPair = toolPathFromSkylark((SkylarkInfo) toolPath);
toolPathPairs.add(toolPathPair);
cToolchain.addToolPath(
@@ -803,6 +808,7 @@
ImmutableList.Builder<Pair<String, String>> makeVariablePairs = ImmutableList.builder();
for (Object makeVariable : makeVariables) {
+ checkRightSkylarkInfoProvider(makeVariable, "make_variables", "MakeVariableInfo");
Pair<String, String> makeVariablePair = makeVariableFromSkylark((SkylarkInfo) makeVariable);
makeVariablePairs.add(makeVariablePair);
cToolchain.addMakeVariable(
@@ -850,6 +856,20 @@
cToolchain.build().toString());
}
+ private static void checkRightSkylarkInfoProvider(
+ Object o, String parameterName, String expectedProvider) throws EvalException {
+ if (!(o instanceof SkylarkInfo)) {
+ throw new EvalException(
+ Location.BUILTIN,
+ String.format(
+ "'%s' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+ + " of type '%s' instead of a '%s' provider. Use the methods provided in"
+ + " https://source.bazel.build/bazel/+/master:tools/cpp/cc_toolchain_config_lib.bzl"
+ + " for obtaining the right providers.",
+ parameterName, EvalUtils.getDataTypeName(o), expectedProvider));
+ }
+ }
+
/** Checks whether the {@link SkylarkInfo} is of the required type. */
private static void checkRightProviderType(SkylarkInfo provider, String type)
throws EvalException {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index b3ad255..ae24710 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -4789,6 +4789,87 @@
}
@Test
+ public void testWrongElementTypeInListParameter_features() throws Exception {
+ getBasicCcToolchainConfigInfoWithAdditionalParameter(
+ "features = ['string_instead_of_feature']");
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//foo:r");
+ assertContainsEvent(
+ "'features' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+ + " of type 'string' instead of a 'FeatureInfo' provider.");
+ }
+
+ @Test
+ public void testWrongElementTypeInListParameter_actionConfigs() throws Exception {
+ getBasicCcToolchainConfigInfoWithAdditionalParameter("action_configs = [None]");
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//foo:r");
+ assertContainsEvent(
+ "'action_configs' parameter of cc_common.create_cc_toolchain_config_info() contains an"
+ + " element of type 'NoneType' instead of a 'ActionConfigInfo' provider.");
+ }
+
+ @Test
+ public void testWrongElementTypeInListParameter_artifactNamePatterns() throws Exception {
+ getBasicCcToolchainConfigInfoWithAdditionalParameter("artifact_name_patterns = [1]");
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//foo:r");
+ assertContainsEvent(
+ "'artifact_name_patterns' parameter of cc_common.create_cc_toolchain_config_info()"
+ + " contains an element of type 'int' instead of a 'ArtifactNamePatternInfo'"
+ + " provider.");
+ }
+
+ @Test
+ public void testWrongElementTypeInListParameter_makeVariables() throws Exception {
+ getBasicCcToolchainConfigInfoWithAdditionalParameter("make_variables = [True]");
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//foo:r");
+ assertContainsEvent(
+ "'make_variables' parameter of cc_common.create_cc_toolchain_config_info() contains an"
+ + " element of type 'bool' instead of a 'MakeVariableInfo' provider.");
+ }
+
+ @Test
+ public void testWrongElementTypeInListParameter_toolPaths() throws Exception {
+ getBasicCcToolchainConfigInfoWithAdditionalParameter("tool_paths = [{}]");
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//foo:r");
+ assertContainsEvent(
+ "'tool_paths' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+ + " of type 'dict' instead of a 'ToolPathInfo' provider.");
+ }
+
+ private void getBasicCcToolchainConfigInfoWithAdditionalParameter(String s) throws Exception {
+ scratch.file(
+ "foo/crosstool.bzl",
+ "def _impl(ctx):",
+ " return cc_common.create_cc_toolchain_config_info(",
+ " ctx = ctx,",
+ " toolchain_identifier = 'toolchain',",
+ " host_system_name = 'host',",
+ " target_system_name = 'target',",
+ " target_cpu = 'cpu',",
+ " target_libc = 'libc',",
+ " compiler = 'compiler',",
+ " abi_libc_version = 'abi_libc',",
+ " abi_version = 'abi',",
+ " " + s + ",",
+ " )",
+ "cc_toolchain_config_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {},",
+ " provides = [CcToolchainConfigInfo], ",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
+ "cc_toolchain_alias(name='alias')",
+ "cc_toolchain_config_rule(name='r')");
+ }
+
+ @Test
public void testGetLegacyCcFlagsMakeVariable() throws Exception {
AnalysisMock.get()
.ccSupport()