[CommandLine] Remove `may only occur zero or one times!` error

Early adoption of new technologies or adjusting certain code generation/IR optimization thresholds
is often available through some cl::opt options (which have unstable surfaces).
Specifying such an option twice will lead to an error.

```
% clang -c a.c -mllvm -disable-binop-extract-shuffle -mllvm -disable-binop-extract-shuffle
clang (LLVM option parsing): for the --disable-binop-extract-shuffle option: may only occur zero or one times!
% clang -c a.c -mllvm -hwasan-instrument-reads=0 -mllvm -hwasan-instrument-reads=0
clang (LLVM option parsing): for the --hwasan-instrument-reads option: may only occur zero or one times!
% clang -c a.c -mllvm --scalar-evolution-max-arith-depth=32 -mllvm --scalar-evolution-max-arith-depth=16
clang (LLVM option parsing): for the --scalar-evolution-max-arith-depth option: may only occur zero or one times!
```

The option is specified twice, because there is sometimes a global setting and
a specific file or project may need to override (or duplicately specify) the
value.

The error is contrary to the common practice of getopt/getopt_long command line
utilities that let the last option win and the `getLastArg` behavior used by
Clang driver options. I have seen such errors for several times. I think the
error just makes users inconvenient, while providing very little value on
discouraging production usage of unstable surfaces (this goal is itself
controversial, because developers might not want to commit to a stable surface
too early, or there is just some subtle codegen toggle which is infeasible to
have a driver option). Therefore, I suggest we drop the diagnostic, at least
before the diagnostic gets sufficiently better support for the overridding needs.

Removing the error is a degraded error checking experience. I think this error
checking behavior, if desirable, should be enabled explicitly by tools. Users
preferring the behavior can figure out a way to do so.

Reviewed By: jhenderson, rnk

Differential Revision: https://reviews.llvm.org/D120455
This commit is contained in:
Fangrui Song 2022-03-11 11:25:04 -08:00
parent 68099b1d5c
commit bd0bddc1ea
7 changed files with 22 additions and 39 deletions

View File

@ -1737,21 +1737,6 @@ bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,
if (!MultiArg)
NumOccurrences++; // Increment the number of times we have been seen
switch (getNumOccurrencesFlag()) {
case Optional:
if (NumOccurrences > 1)
return error("may only occur zero or one times!", ArgName);
break;
case Required:
if (NumOccurrences > 1)
return error("must occur exactly one time!", ArgName);
LLVM_FALLTHROUGH;
case OneOrMore:
case ZeroOrMore:
case ConsumeAfter:
break;
}
return handleOccurrence(pos, ArgName, Value);
}

View File

@ -4,8 +4,10 @@
# RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o
# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc
# RUN: rm -rf %t.lib
# RUN: rm -rf %t.lib %t2.lib
# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o %t-x86_64.bc
# RUN: llvm-libtool-darwin -static -o %t2.lib -o %t.lib %t-input1.o %t-input2.o %t-x86_64.bc
# RUN: not ls %t2.lib
## Check that binaries are present:
# RUN: llvm-ar t %t.lib | \

View File

@ -24,16 +24,12 @@
# CHECK-NONDETERMINISTIC: {{[[:space:]]1995[[:space:]]}}
## D Flag specified more than once:
# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -D -D 2>&1 | \
# RUN: FileCheck %s --check-prefix=CHECK-ERROR-D
# CHECK-ERROR-D: for the -D option: may only occur zero or one times!
# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o -D -D 2>&1 | count 0
# RUN: env TZ=GMT llvm-ar tv %t.lib | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
## U Flag specified more than once:
# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -U -U 2>&1 | \
# RUN: FileCheck %s --check-prefix=CHECK-ERROR-U
# CHECK-ERROR-U: for the -U option: may only occur zero or one times!
# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o -U -U 2>&1 | count 0
# RUN: env TZ=GMT llvm-ar tv %t.lib | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
## Both D and U flags specified:
# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -D -U 2>&1 | \

View File

@ -30,10 +30,10 @@
# RUN: rm -rf %t/dirname && mkdir -p %t/dirname
# RUN: yaml2obj %S/Inputs/input1.yaml -o %t/dirname/%basename_t.tmp-input1.o
# RUN: echo %basename_t.tmp-input1.o > %t.files.txt
# RUN: echo %basename_t.tmp-input1.o > %t.files2.txt
## Passing in dirname:
# RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files.txt,%t/dirname
# RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files2.txt,%t/dirname
# RUN: llvm-ar t %t.lib | \
# RUN: FileCheck %s --check-prefix=DIRNAME-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
# RUN: llvm-nm --print-armap %t.lib | \
@ -46,7 +46,7 @@
# DIRNAME-SYMBOLS-EMPTY:
## Passing both -filelist option and object file as input:
# RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files.txt,%t/dirname %t-input2.o
# RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files2.txt,%t/dirname %t-input2.o
# RUN: llvm-ar t %t.lib | \
# RUN: FileCheck %s --check-prefix=REVERSE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
# RUN: llvm-nm --print-armap %t.lib | \
@ -106,7 +106,6 @@
## Filelist option specified more than once:
# RUN: touch %t.list1.txt and %t.list2.txt
# RUN: not llvm-libtool-darwin -static -o %t.lib -filelist %t.list1.txt -filelist %t.list2.txt 2>&1 | \
# RUN: FileCheck %s --check-prefix=DUPLICATE-ERROR
# DUPLICATE-ERROR: for the --filelist option: may only occur zero or one times!
# RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.empty-list -filelist %t.files.txt 2>&1
# RUN: llvm-ar t %t.lib | \
# RUN: FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp

View File

@ -18,12 +18,6 @@
# MISSING: for the -o option: requires a value!
## Passing in two output files:
# RUN: not llvm-libtool-darwin -static %t.input -o %t.lib1 -o %t.lib2 2>&1 | \
# RUN: FileCheck %s --check-prefix=DOUBLE-OUTPUT
# DOUBLE-OUTPUT: for the -o option: may only occur zero or one times!
## Input file not found:
# RUN: not llvm-libtool-darwin -static -o %t.lib %t.missing 2>&1 | \
# RUN: FileCheck %s --check-prefix=NO-FILE -DFILE=%t.missing -DMSG=%errc_ENOENT

View File

@ -420,6 +420,14 @@ TEST(CommandLineTest, HideUnrelatedOptionsMulti) {
<< "Hid default option that should be visable.";
}
TEST(CommandLineTest, SetMultiValues) {
StackOption<int> Option("option");
const char *args[] = {"prog", "-option=1", "-option=2"};
EXPECT_TRUE(cl::ParseCommandLineOptions(array_lengthof(args), args,
StringRef(), &llvm::nulls()));
EXPECT_EQ(Option, 2);
}
TEST(CommandLineTest, SetValueInSubcategories) {
cl::ResetCommandLineParser();

View File

@ -2,7 +2,7 @@
// RUN: not mlir-opt %s -pass-pipeline='builtin.module(test-module-pass{test-option=3})' 2>&1 | FileCheck --check-prefix=CHECK_ERROR_2 %s
// RUN: not mlir-opt %s -pass-pipeline='builtin.module(builtin.func(test-options-pass{list=3}), test-module-pass{invalid-option=3})' 2>&1 | FileCheck --check-prefix=CHECK_ERROR_3 %s
// RUN: not mlir-opt %s -pass-pipeline='test-options-pass{list=3 list=notaninteger}' 2>&1 | FileCheck --check-prefix=CHECK_ERROR_4 %s
// RUN: not mlir-opt %s -pass-pipeline='builtin.func(test-options-pass{list=1,2,3,4 list=5 string=value1 string=value2})' 2>&1 | FileCheck --check-prefix=CHECK_ERROR_5 %s
// RUN: mlir-opt %s -pass-pipeline='builtin.func(test-options-pass{list=1,2,3,4 list=5 string=value1 string=value2})'
// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.func(test-options-pass{string-list=a list=1,2,3,4 string-list=b,c list=5 string-list=d string=nested_pipeline{arg1=10 arg2=" {} " arg3=true}})' -test-dump-pipeline 2>&1 | FileCheck --check-prefix=CHECK_1 %s
// RUN: mlir-opt %s -verify-each=false -test-options-pass-pipeline='list=1 string-list=a,b' -test-dump-pipeline 2>&1 | FileCheck --check-prefix=CHECK_2 %s
// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(builtin.func(test-options-pass{list=3}), builtin.func(test-options-pass{list=1,2,3,4}))' -test-dump-pipeline 2>&1 | FileCheck --check-prefix=CHECK_3 %s
@ -11,7 +11,6 @@
// CHECK_ERROR_2: no such option test-option
// CHECK_ERROR_3: no such option invalid-option
// CHECK_ERROR_4: 'notaninteger' value invalid for integer argument
// CHECK_ERROR_5: string option: may only occur zero or one times
// CHECK_1: test-options-pass{list=1,2,3,4,5 string=nested_pipeline{arg1=10 arg2=" {} " arg3=true} string-list=a,b,c,d}
// CHECK_2: test-options-pass{list=1 string= string-list=a,b}