[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:
Thirumalai Shaktivel 2026-06-15 08:51:24 +05:30 committed by GitHub
parent ee5856d8a8
commit 625facd437
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 10 deletions

View file

@ -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

View file

@ -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