Reland "[WebAssembly] Add linker options to control feature checking"
Do not pipe binary data between processes in lit tests this time,
since it turns out that can break on Windows.
This reverts commit 84c8652fc3085155d0f9c355455e5a797c6d9db6.
llvm-svn: 356975
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 897908a..5f12ce7 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -878,18 +878,30 @@
}
void Writer::calculateTargetFeatures() {
+ SmallSet<std::string, 8> Used;
SmallSet<std::string, 8> Required;
SmallSet<std::string, 8> Disallowed;
+ // Only infer used features if user did not specify features
+ bool InferFeatures = !Config->Features.hasValue();
+
+ if (!InferFeatures) {
+ for (auto &Feature : Config->Features.getValue())
+ TargetFeatures.insert(Feature);
+ // No need to read or check features
+ if (!Config->CheckFeatures)
+ return;
+ }
+
// Find the sets of used, required, and disallowed features
for (ObjFile *File : Symtab->ObjectFiles) {
for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
switch (Feature.Prefix) {
case WASM_FEATURE_PREFIX_USED:
- TargetFeatures.insert(Feature.Name);
+ Used.insert(Feature.Name);
break;
case WASM_FEATURE_PREFIX_REQUIRED:
- TargetFeatures.insert(Feature.Name);
+ Used.insert(Feature.Name);
Required.insert(Feature.Name);
break;
case WASM_FEATURE_PREFIX_DISALLOWED:
@@ -902,6 +914,20 @@
}
}
+ if (InferFeatures)
+ TargetFeatures.insert(Used.begin(), Used.end());
+
+ if (!Config->CheckFeatures)
+ return;
+
+ // Validate that used features are allowed in output
+ if (!InferFeatures) {
+ for (auto &Feature : Used) {
+ if (!TargetFeatures.count(Feature))
+ error(Twine("Target feature '") + Feature + "' is not allowed.");
+ }
+ }
+
// Validate the required and disallowed constraints for each file
for (ObjFile *File : Symtab->ObjectFiles) {
SmallSet<std::string, 8> ObjectFeatures;
@@ -910,11 +936,13 @@
continue;
ObjectFeatures.insert(Feature.Name);
if (Disallowed.count(Feature.Name))
- error("Target feature \"" + Feature.Name + "\" is disallowed");
+ error(Twine("Target feature '") + Feature.Name +
+ "' is disallowed. Use --no-check-features to suppress.");
}
for (auto &Feature : Required) {
if (!ObjectFeatures.count(Feature))
- error(Twine("Missing required target feature \"") + Feature + "\"");
+ error(Twine("Missing required target feature '") + Feature +
+ "'. Use --no-check-features to suppress.");
}
}
}