[Flang] Store only options in FLANG_COMPILER_OPTIONS_STRING (#201278)
Previously, FLANG_COMPILER_OPTIONS_STRING stored every argument passed
to the flang driver, including input file names. The GNU extension
compiler_options() is documented to return only the options, not the
input files. Including the input files also caused the string to exceed
ARG_MAX on large builds, producing:
posix_spawn failed: Argument list too long
Use the driver's parsed InputArgList to filter out OPT_INPUT arguments,
preserving all options and their values (e.g. `-I /path`, `-o file`).
Fixes: https://github.com/llvm/llvm-project/issues/170651
This commit is contained in:
parent
ee5856d8a8
commit
625facd437
2 changed files with 18 additions and 10 deletions
|
|
@ -1,6 +1,6 @@
|
|||
! RUN: %flang -S -emit-llvm -o - %s | FileCheck %s
|
||||
! Test communication of COMPILER_OPTIONS from flang to flang -fc1.
|
||||
! CHECK: [[OPTSVAR:@_QQclX[0-9a-f]+]] = {{[a-z]+}} constant [[[OPTSLEN:[0-9]+]] x i8] c"{{.*}}flang{{(\.exe)?}} {{.*}}-S -emit-llvm -o - {{.*}}compiler-options.f90"
|
||||
! CHECK: [[OPTSVAR:@_QQclX[0-9A-Fa-f]+]] = {{[a-z]+}} constant [[[OPTSLEN:[0-9]+]] x i8] c"-S -emit-llvm -o -"
|
||||
program main
|
||||
use ISO_FORTRAN_ENV, only: compiler_options
|
||||
implicit none
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "clang/Basic/DiagnosticIDs.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
|
|
@ -174,22 +175,29 @@ int main(int argc, const char **argv) {
|
|||
if (rejectAssemblyInputs(c->getInputArgs(), diags))
|
||||
return 1;
|
||||
|
||||
// Set the environment variable, FLANG_COMPILER_OPTIONS_STRING, to contain all
|
||||
// the compiler options. This is intended for the frontend driver,
|
||||
// flang -fc1, to enable the implementation of the COMPILER_OPTIONS
|
||||
// intrinsic. To this end, the frontend driver requires the list of the
|
||||
// original compiler options, which is not available through other means.
|
||||
// Set the environment variable, FLANG_COMPILER_OPTIONS_STRING, to contain
|
||||
// the compiler options (excluding input file names and the program name).
|
||||
// This is intended for the frontend driver, flang -fc1, to enable the
|
||||
// implementation of the COMPILER_OPTIONS intrinsic. To this end, the
|
||||
// frontend driver requires the list of the original compiler options,
|
||||
// which is not available through other means.
|
||||
// TODO: This way of passing information between the compiler and frontend
|
||||
// drivers is discouraged. We should find a better way not involving env
|
||||
// variables.
|
||||
std::string compilerOptsGathered;
|
||||
llvm::raw_string_ostream os(compilerOptsGathered);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
os << argv[i];
|
||||
if (i < argc - 1) {
|
||||
os << ' ';
|
||||
const llvm::opt::InputArgList &argList = c->getInputArgs();
|
||||
bool first = true;
|
||||
for (const llvm::opt::Arg *arg : argList) {
|
||||
if (!arg->getOption().matches(clang::options::OPT_INPUT)) {
|
||||
if (!first) {
|
||||
os << ' ';
|
||||
}
|
||||
os << arg->getAsString(argList);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_putenv_s("FLANG_COMPILER_OPTIONS_STRING", compilerOptsGathered.c_str());
|
||||
#else
|
||||
|
|
|
|||
Loading…
Reference in a new issue