Page MenuHomePhabricator

[driver] Make `clang` warn rather then error on `flang` options
AcceptedPublic

Authored by awarzynski on Mar 25 2021, 10:24 AM.

Details

Summary

This patch adds extra logic in Driver::ParseArgStrings so that clang
(Clang's compiler driver) generates a warning when a Flang-only option
is used. Previously it would throw an error:

  • error: unknown argument: <option>

and exit immediately. That was flagged as problematic in [1].

The new behaviour is consistent with GCC:

gcc -c  -ffree-form  file.c
cc1: warning: command line option ‘-ffree-form’ is valid for Fortran but not for C

It allows users to use clang as e.g. a linker driver, without worrying
about passing Fortran specific flags to clang. These flags are often
embedded in build systems and are hard to extract just for linking.
An issue like this raised in [1]. This patch is an attempt to address
this.

The current approach is a bit verbose. Ideally we should extend the
OptTable API to make accommodating for situations like this easier. In
particular, I'm not sure whether we can add similar logic for Flang.
In this patch we are relying on the FlangOnlyOption flag to
identify problematic options. There's no equivalent flag for Clang-only
options. I propose that we address this later, when this becomes a
problem for Flang.

[1] https://reviews.llvm.org/D95460

Diff Detail

Unit TestsFailed

TimeTest
80 msx64 windows > Clang.Driver::flang-only-option-diags.c
Script: -- : 'RUN: at line 4'; c:\ws\w16n2-1\llvm-project\premerge-checks\build\bin\clang.exe -fsyntax-only -ffree-form C:\ws\w16n2-1\llvm-project\premerge-checks\clang\test\Driver\flang-only-option-diags.c 2>&1 | c:\ws\w16n2-1\llvm-project\premerge-checks\build\bin\filecheck.exe C:\ws\w16n2-1\llvm-project\premerge-checks\clang\test\Driver\flang-only-option-diags.c --check-prefix=WARNING
420 msx64 windows > Clang.Driver::flang-only-options.c
Script: -- : 'RUN: at line 5'; c:\ws\w16n2-1\llvm-project\premerge-checks\build\bin\clang.exe -fsyntax-only -ffree-form -ffixed-form -module-dir -ffixed-line-length=1 -fopenacc -fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 -flarge-sizes -fbackslash -fno-backslash -fxor-operator -fno-xor-operator -flogical-abbreviations -fno-logical-abbreviations -fimplicit-none -fno-implicit-none -falternative-parameter-statement -fintrinsic-modules-path -test-io -fdebug-unparse -fdebug-unparse-with-symbols -fdebug-dump-symbols -fdebug-dump-parse-tree -fdebug-dump-provenance -fdebug-dump-parsing-log -fdebug-measure-parse-tree -fdebug-pre-fir-tree -fdebug-module-writer -fget-symbols-sources C:\ws\w16n2-1\llvm-project\premerge-checks\clang\test\Driver\flang-only-options.c 2>&1 | c:\ws\w16n2-1\llvm-project\premerge-checks\build\bin\filecheck.exe C:\ws\w16n2-1\llvm-project\premerge-checks\clang\test\Driver\flang-only-options.c

Event Timeline

awarzynski created this revision.Mar 25 2021, 10:24 AM
awarzynski requested review of this revision.Mar 25 2021, 10:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 25 2021, 10:24 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

I've not had a chance to add tests yet. I will add them shortly.

@protze.joachim , hopefully this addresses the issues that you raised in https://reviews.llvm.org/D95460. Please, could you verify before I update this? I want to make sure that this is the right approach. Thank you!

awarzynski added a project: Restricted Project.

Thank you for working on this! It works for me.
As you mentioned in D95460, this makes the behavior more similar to gcc.

I tested with -Werror:

$ flang -fopenmp test-f77.f -ffree-form -c
$ clang -fopenmp test-f77.o -ffree-form -lgfortran -Werror && echo $?
clang-13: warning: command line option ‘-ffree-form’ is only valid in Flang mode (i.e. for Fortran input)
clang-13: error: argument unused during compilation: '-ffree-form' [-Werror,-Wunused-command-line-argument]

Since -Werror only raises the second warning, -Wno-error=unused-command-line-argument allows to successfully compile with -Werror.

$ clang -fopenmp test-f77.o -ffree-form -lgfortran -Werror -Wno-error=unused-command-line-argument && echo $?
clang-13: warning: command line option ‘-ffree-form’ is only valid in Flang mode (i.e. for Fortran input)
clang-13: warning: argument unused during compilation: '-ffree-form' [-Wunused-command-line-argument]
0

I also tested with -ffixed-form and -ffixed-line-length-132. The latter doesn't work, while -ffixed-line-length=132 works.

Hi @protze.joachim , thank you for testing this so thoroughly!

I tested with -Werror:

$ flang -fopenmp test-f77.f -ffree-form -c
$ clang -fopenmp test-f77.o -ffree-form -lgfortran -Werror && echo $?
clang-13: warning: command line option ‘-ffree-form’ is only valid in Flang mode (i.e. for Fortran input)
clang-13: error: argument unused during compilation: '-ffree-form' [-Werror,-Wunused-command-line-argument]

Since -Werror only raises the second warning, -Wno-error=unused-command-line-argument allows to successfully compile with -Werror.

I think that -Werror should also elevate the first warning to an error. This can be fixed by creating a definition for the diagnostic in clang/include/clang/Basic/DiagnosticDriverKinds.td.

I also tested with -ffixed-form and -ffixed-line-length-132. The latter doesn't work, while -ffixed-line-length=132 works.

Tl;Dr I haven't figured yet how to make this work for options that are aliases.
Longer version:
This is caused by the fact that ffixed-line-length-132 is an alias for ffixed-line-length=132. When parsing options, the OptTable API will skip unknown options (e.g. options marked with FlangOnlyOption when in Clang mode) and represent them internally as OPT_UNKNOWN. This happens in Optable.cpp. Options that are "unknown" contain no information, so it's impossible to check their aliases (or whether they alias some other option). This is problematic as options/args are converted to their unaliased forms when created (see here).

Btw, how important are these aliases for you?

awarzynski updated this revision to Diff 335270.Apr 5 2021, 9:00 AM

Refine the behaviour when using diag options and add tests

  • -Werror will now elevate the warning generated here to an error. This is consistent with gcc. To this end I had to create a new diagnostic in DiagnosticDriverKinds.td.
  • Added tests for the logic implemented here.
awarzynski updated this revision to Diff 335275.Apr 5 2021, 9:21 AM

Add more reviewers and remove unrelated changes (apologies for the noise!)

awarzynski added inline comments.Apr 5 2021, 9:22 AM
clang/lib/Driver/Driver.cpp
294–297

This is how we could deal with aliased options, but currently A->getAlias() always returns nullptr.

ashermancinelli accepted this revision.Apr 6 2021, 10:22 AM
This revision is now accepted and ready to land.Apr 6 2021, 10:22 AM

Btw, how important are these aliases for you?

I can work with -ffixed-line-length=132 where needed. It's just not obvious from flang --help that this is an alias for -ffixed-line-length-132 (or the other way around). I only learned that by looking at LLVM source.

awarzynski added a comment.EditedApr 7 2021, 8:53 AM

Btw, how important are these aliases for you?

It's just not obvious from flang --help that this is an alias for -ffixed-line-length-132 (or the other way around). I only learned that by looking at LLVM source.

It's the other way round :) -ffixed-line-length-132 is an alias for -ffixed-line-length=132. If you run flang-new --help, then you will only see non-aliases. Hopefully that will help navigating this.

I don't have a solution for aliases, I'd need more time for this. Long term we should definitely aim for something more general, but for now I'd like to focus on making sure that:

  • you are no longer blocked, and
  • we are not introducing anything that could block/disable other important use cases.

Btw, I hope that you meant flang-new --help (the new driver, based on libClangDriver) rather than flang --help (the "throwaway" driver that we want to replace in the near future).

awarzynski updated this revision to Diff 336075.Apr 8 2021, 6:07 AM

Refine comments, remove code for aliases (which didn't work anyway)

tstellar added a subscriber: tstellar.