This is an archive of the discontinued LLVM Phabricator instance.

OptTable: stop parsing options after "--" alone.
Needs ReviewPublic

Authored by t.p.northover on May 15 2023, 6:21 AM.

Details

Reviewers
jhenderson
Summary

Conventionally, -- on its own tells a command to stop parsing further options and treat all future arguments as positional inputs. Used to act on pesky files starting with -, and possibly other things.

I wasn't entirely sure it should apply to all tools, but it seems like a reasonable default position to take. And the -- would have been a hard error (unknown option) for all existing backends anyway so I don't think it can break anyone.

Diff Detail

Event Timeline

t.p.northover created this revision.May 15 2023, 6:21 AM
Herald added a project: Restricted Project. · View Herald Transcript
t.p.northover requested review of this revision.May 15 2023, 6:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 15 2023, 6:21 AM
Herald added a subscriber: MaskRay. · View Herald Transcript

I feel like this is a non-trivial change that requires greater visibility and buy-in from the community. I personally have no issues with it, but I think it's worth raising on the LLVM Discourse channel.

llvm/test/tools/llvm-nm/option--.test
2

I don't think a test in tools/llvm-nm is the right place for this sort of behaviour, as it isn't code that is specific to llvm-nm. Can it be tested using the gtest unit test system? If not, then the test still would belong in llvm/test/Option or something like that.

MaskRay added a comment.EditedMay 18 2023, 4:01 PM

This behavior makes sense to me. This is llvm/lib/SupportCommandLine.cpp and GNU getopt_long's behavior, used by a lot of utilities, well beyond GNU. (The convention might be by others?)

POSIX considers -- special as well.

argv[optind]   points to the string "--"

getopt() shall return -1 after incrementing optind.

clang/include/clang/Driver/Options.td currently defines def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>, and this change will change the behavior and cause some interesting interop issues (I don't investigate closely) with D98824.

% gcc -- -E a.c
gcc: error: unrecognized command-line option ‘--’
% clang -- -E a.c
clang: error: no such file or directory: '-E'
% as -- a.c
waiting for stdin as if `--` is spelled as `-`. I think this is gas's bug.
llvm/test/tools/llvm-nm/option--.test
2

The test can be added to llvm/unittests/Option/OptionParsingTest.cpp

3

The message is OS dependent. We can use %errc_ENOENT (see llvm/docs/TestingGuide.rst).

Sorry about this, but I hadn't realised Clang itself used this library until you mentioned the behaviour there. And that led me to test failures with clang-linker-wrapper (already does something similar, but really weirdly) and clang-scan-deps. And it turns out this faciliy already pretty much exists but is setup in the option table.

I'd kind of prefer opt out personally (it's a niche use-case, but you'd probably want it more than not when it comes up). But being able to control it is definitely better than my original patch so I rewrote it to only affect llvm-nm after all.

Switch to existing solution for this. I think that makes the llvm-nm test probably the right place again so I've left it.

Test was leaving stray files in the source dir.

MaskRay added a comment.EditedJun 6 2023, 8:51 AM

The patch looks good to me. It's a shame that we have to explicitly teach a tool to use OPT_DASH_DASH instead of making this a built-in feature of LLVMOption and making the feature opt-out (-- is an overwhelming convention and usually a tool needs arguments to not obey that).
That said, accepting -- in llvm-nm is still a good change.

@jhenderson usually has strong opinions on option handling and should sign off on this patch.

llvm/test/tools/llvm-nm/option--.test
2

See llvm/docs/TestingGuide.rst:692 %errc_ENOENT

5

to prevent issues when %t already exists as a file or exists as a directory with existing files potentially intervening with this test execution.

I think def DASH_DASH and if (opt::Arg *A = Args.getLastArgNoClaim(OPT_DASH_DASH)) will probably be non-ergonomic for most tools. I created D152286 [Option] Support special argument "--".

Sorry for the silence: I've been only doing minimal levels of reviewing the past couple of weeks, and this week isn't shaping up to be much better for various reasons. This patch looks good, aside from the hard-coded error message in the check (see @MaskRay's inline comment) which is causing a test failure on Windows., but a more general solution would be better if possible, so I suggest this is parked until D152286 has landed or otherwise.