forked from OSchip/llvm-project
[WebAssembly] Improve feature validation error messages
Summary: Add the names of the input files responsible for each error to the messages. Reviewers: sbc100, azakai Subscribers: dschuff, jgravelle-google, aheejin, sunfish, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62704 llvm-svn: 362162
This commit is contained in:
parent
6ada11f134
commit
86e73f51d7
|
@ -57,4 +57,4 @@ Sections:
|
||||||
# NO-SHARED-NEXT: - Initial: 0x00000002
|
# NO-SHARED-NEXT: - Initial: 0x00000002
|
||||||
# NO-SHARED-NOT: Maximum:
|
# NO-SHARED-NOT: Maximum:
|
||||||
|
|
||||||
# SHARED: 'atomics' feature is disallowed, so --shared-memory must not be used{{$}}
|
# SHARED: 'atomics' feature is disallowed by {{.*}}shared-memory-no-atomics.yaml.tmp1.o, so --shared-memory must not be used{{$}}
|
||||||
|
|
|
@ -51,7 +51,7 @@ Sections:
|
||||||
# SPECIFIED-NEXT: Name: foo
|
# SPECIFIED-NEXT: Name: foo
|
||||||
# SPECIFIED-NEXT: ...
|
# SPECIFIED-NEXT: ...
|
||||||
|
|
||||||
# UNSPECIFIED: Target feature 'foo' is not allowed.{{$}}
|
# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-required.yaml.tmp1.o is not allowed.{{$}}
|
||||||
|
|
||||||
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
|
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
|
||||||
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
|
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
|
||||||
|
@ -71,7 +71,7 @@ Sections:
|
||||||
# REQUIRED-NEXT: Name: foo
|
# REQUIRED-NEXT: Name: foo
|
||||||
# REQUIRED-NEXT: ...
|
# REQUIRED-NEXT: ...
|
||||||
|
|
||||||
# DISALLOWED: Target feature 'foo' is disallowed. Use --no-check-features to suppress.{{$}}
|
# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-required.yaml.tmp1.o is disallowed by {{.*}}target-feature-required.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
|
||||||
|
|
||||||
# DISALLOWED-NOCHECK: - Type: CUSTOM
|
# DISALLOWED-NOCHECK: - Type: CUSTOM
|
||||||
# DISALLOWED-NOCHECK-NEXT: Name: target_features
|
# DISALLOWED-NOCHECK-NEXT: Name: target_features
|
||||||
|
@ -80,7 +80,7 @@ Sections:
|
||||||
# DISALLOWED-NOCHECK-NEXT: Name: foo
|
# DISALLOWED-NOCHECK-NEXT: Name: foo
|
||||||
# DISALLOWED-NOCHECK-NEXT: ...
|
# DISALLOWED-NOCHECK-NEXT: ...
|
||||||
|
|
||||||
# NONE: Missing required target feature 'foo'. Use --no-check-features to suppress.{{$}}
|
# NONE: Missing target feature 'foo' in {{.*}}target-feature-required.yaml.tmp.none.o, required by {{.*}}target-feature-required.yaml.tmp1.o. Use --no-check-features to suppress.{{$}}
|
||||||
|
|
||||||
# NONE-NOCHECK: - Type: CUSTOM
|
# NONE-NOCHECK: - Type: CUSTOM
|
||||||
# NONE-NOCHECK-NEXT: Name: target_features
|
# NONE-NOCHECK-NEXT: Name: target_features
|
||||||
|
|
|
@ -53,7 +53,7 @@ Sections:
|
||||||
# SPECIFIED-NEXT: Name: foo
|
# SPECIFIED-NEXT: Name: foo
|
||||||
# SPECIFIED-NEXT: ...
|
# SPECIFIED-NEXT: ...
|
||||||
|
|
||||||
# UNSPECIFIED: Target feature 'foo' is not allowed.{{$}}
|
# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-used.yaml.tmp1.o is not allowed.{{$}}
|
||||||
|
|
||||||
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
|
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
|
||||||
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
|
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
|
||||||
|
@ -80,7 +80,7 @@ Sections:
|
||||||
# REQUIRED-NEXT: Name: foo
|
# REQUIRED-NEXT: Name: foo
|
||||||
# REQUIRED-NEXT: ...
|
# REQUIRED-NEXT: ...
|
||||||
|
|
||||||
# DISALLOWED: Target feature 'foo' is disallowed. Use --no-check-features to suppress.{{$}}
|
# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-used.yaml.tmp1.o is disallowed by {{.*}}target-feature-used.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
|
||||||
|
|
||||||
# DISALLOWED-NOCHECK: - Type: CUSTOM
|
# DISALLOWED-NOCHECK: - Type: CUSTOM
|
||||||
# DISALLOWED-NOCHECK-NEXT: Name: target_features
|
# DISALLOWED-NOCHECK-NEXT: Name: target_features
|
||||||
|
|
|
@ -348,9 +348,9 @@ void Writer::finalizeSections() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::populateTargetFeatures() {
|
void Writer::populateTargetFeatures() {
|
||||||
SmallSet<std::string, 8> Used;
|
StringMap<std::string> Used;
|
||||||
SmallSet<std::string, 8> Required;
|
StringMap<std::string> Required;
|
||||||
SmallSet<std::string, 8> Disallowed;
|
StringMap<std::string> Disallowed;
|
||||||
|
|
||||||
// Only infer used features if user did not specify features
|
// Only infer used features if user did not specify features
|
||||||
bool InferFeatures = !Config->Features.hasValue();
|
bool InferFeatures = !Config->Features.hasValue();
|
||||||
|
@ -365,17 +365,18 @@ void Writer::populateTargetFeatures() {
|
||||||
|
|
||||||
// Find the sets of used, required, and disallowed features
|
// Find the sets of used, required, and disallowed features
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||||
|
StringRef FileName(File->getName());
|
||||||
for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
|
for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
|
||||||
switch (Feature.Prefix) {
|
switch (Feature.Prefix) {
|
||||||
case WASM_FEATURE_PREFIX_USED:
|
case WASM_FEATURE_PREFIX_USED:
|
||||||
Used.insert(Feature.Name);
|
Used.insert({Feature.Name, FileName});
|
||||||
break;
|
break;
|
||||||
case WASM_FEATURE_PREFIX_REQUIRED:
|
case WASM_FEATURE_PREFIX_REQUIRED:
|
||||||
Used.insert(Feature.Name);
|
Used.insert({Feature.Name, FileName});
|
||||||
Required.insert(Feature.Name);
|
Required.insert({Feature.Name, FileName});
|
||||||
break;
|
break;
|
||||||
case WASM_FEATURE_PREFIX_DISALLOWED:
|
case WASM_FEATURE_PREFIX_DISALLOWED:
|
||||||
Disallowed.insert(Feature.Name);
|
Disallowed.insert({Feature.Name, FileName});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Unrecognized feature policy prefix " +
|
error("Unrecognized feature policy prefix " +
|
||||||
|
@ -385,41 +386,52 @@ void Writer::populateTargetFeatures() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InferFeatures)
|
if (InferFeatures)
|
||||||
Out.TargetFeaturesSec->Features.insert(Used.begin(), Used.end());
|
Out.TargetFeaturesSec->Features.insert(Used.keys().begin(),
|
||||||
|
Used.keys().end());
|
||||||
|
|
||||||
if (Out.TargetFeaturesSec->Features.count("atomics") && !Config->SharedMemory)
|
if (Out.TargetFeaturesSec->Features.count("atomics") &&
|
||||||
error("'atomics' feature is used, so --shared-memory must be used");
|
!Config->SharedMemory) {
|
||||||
|
if (InferFeatures)
|
||||||
|
error(Twine("'atomics' feature is used by ") + Used["atomics"] +
|
||||||
|
", so --shared-memory must be used");
|
||||||
|
else
|
||||||
|
error("'atomics' feature is used, so --shared-memory must be used");
|
||||||
|
}
|
||||||
|
|
||||||
if (!Config->CheckFeatures)
|
if (!Config->CheckFeatures)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Disallowed.count("atomics") && Config->SharedMemory)
|
if (Disallowed.count("atomics") && Config->SharedMemory)
|
||||||
error(
|
error("'atomics' feature is disallowed by " + Disallowed["atomics"] +
|
||||||
"'atomics' feature is disallowed, so --shared-memory must not be used");
|
", so --shared-memory must not be used");
|
||||||
|
|
||||||
// Validate that used features are allowed in output
|
// Validate that used features are allowed in output
|
||||||
if (!InferFeatures) {
|
if (!InferFeatures) {
|
||||||
for (auto &Feature : Used) {
|
for (auto &Feature : Used.keys()) {
|
||||||
if (!Out.TargetFeaturesSec->Features.count(Feature))
|
if (!Out.TargetFeaturesSec->Features.count(Feature))
|
||||||
error(Twine("Target feature '") + Feature + "' is not allowed.");
|
error(Twine("Target feature '") + Feature + "' used by " +
|
||||||
|
Used[Feature] + " is not allowed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the required and disallowed constraints for each file
|
// Validate the required and disallowed constraints for each file
|
||||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||||
|
StringRef FileName(File->getName());
|
||||||
SmallSet<std::string, 8> ObjectFeatures;
|
SmallSet<std::string, 8> ObjectFeatures;
|
||||||
for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
|
for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
|
||||||
if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
|
if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
|
||||||
continue;
|
continue;
|
||||||
ObjectFeatures.insert(Feature.Name);
|
ObjectFeatures.insert(Feature.Name);
|
||||||
if (Disallowed.count(Feature.Name))
|
if (Disallowed.count(Feature.Name))
|
||||||
error(Twine("Target feature '") + Feature.Name +
|
error(Twine("Target feature '") + Feature.Name + "' used in " +
|
||||||
"' is disallowed. Use --no-check-features to suppress.");
|
FileName + " is disallowed by " + Disallowed[Feature.Name] +
|
||||||
|
". Use --no-check-features to suppress.");
|
||||||
}
|
}
|
||||||
for (auto &Feature : Required) {
|
for (auto &Feature : Required.keys()) {
|
||||||
if (!ObjectFeatures.count(Feature))
|
if (!ObjectFeatures.count(Feature))
|
||||||
error(Twine("Missing required target feature '") + Feature +
|
error(Twine("Missing target feature '") + Feature + "' in " + FileName +
|
||||||
"'. Use --no-check-features to suppress.");
|
", required by " + Required[Feature] +
|
||||||
|
". Use --no-check-features to suppress.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue