From 55abd2b2956f91e3f69b375b22ab0f848e08aa20 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 14 Sep 2019 06:01:22 +0000 Subject: [PATCH] [Driver] Fix multiple bugs related to dependency file options: -M -MM -MD -MMD -MT -MQ -M -o test.i => dependency file is test.d, not test.i -MM -o test.i => dependency file is test.d, not test.i -M -MMD => bogus warning -Wunused-command-line-argument -M MT dummy => -w not rendered llvm-svn: 371918 --- clang/lib/Driver/Driver.cpp | 6 ++-- clang/lib/Driver/ToolChains/Clang.cpp | 64 +++++++++++++++++++---------------- clang/test/Driver/m-and-mm.c | 26 +++++++++++--- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a8a4a3c..861372e 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3450,8 +3450,10 @@ Action *Driver::ConstructPhaseAction( llvm_unreachable("link action invalid here."); case phases::Preprocess: { types::ID OutputTy; - // -{M, MM} alter the output type. - if (Args.hasArg(options::OPT_M, options::OPT_MM)) { + // -M and -MM specify the dependency file name by altering the output type, + // -if -MD and -MMD are not specified. + if (Args.hasArg(options::OPT_M, options::OPT_MM) && + !Args.hasArg(options::OPT_MD, options::OPT_MMD)) { OutputTy = types::TY_Dependencies; } else { OutputTy = Input->getType(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 169b03b..ac3f07d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1061,7 +1061,6 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, ArgStringList &CmdArgs, const InputInfo &Output, const InputInfoList &Inputs) const { - Arg *A; const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU(); CheckPreprocessingOptions(D, Args); @@ -1070,9 +1069,20 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_CC); // Handle dependency file generation. - if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) || - (A = Args.getLastArg(options::OPT_MD)) || - (A = Args.getLastArg(options::OPT_MMD))) { + Arg *ArgM = Args.getLastArg(options::OPT_MM); + if (!ArgM) + ArgM = Args.getLastArg(options::OPT_M); + Arg *ArgMD = Args.getLastArg(options::OPT_MMD); + if (!ArgMD) + ArgMD = Args.getLastArg(options::OPT_MD); + + // -M and -MM imply -w. + if (ArgM) + CmdArgs.push_back("-w"); + else + ArgM = ArgMD; + + if (ArgM) { // Determine the output location. const char *DepFile; if (Arg *MF = Args.getLastArg(options::OPT_MF)) { @@ -1080,8 +1090,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, C.addFailureResultFile(DepFile, &JA); } else if (Output.getType() == types::TY_Dependencies) { DepFile = Output.getFilename(); - } else if (A->getOption().matches(options::OPT_M) || - A->getOption().matches(options::OPT_MM)) { + } else if (!ArgMD) { DepFile = "-"; } else { DepFile = getDependencyFileName(Args, Inputs); @@ -1090,8 +1099,22 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, CmdArgs.push_back("-dependency-file"); CmdArgs.push_back(DepFile); + bool HasTarget = false; + for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) { + HasTarget = true; + A->claim(); + if (A->getOption().matches(options::OPT_MT)) { + A->render(Args, CmdArgs); + } else { + CmdArgs.push_back("-MT"); + SmallString<128> Quoted; + QuoteTarget(A->getValue(), Quoted); + CmdArgs.push_back(Args.MakeArgString(Quoted)); + } + } + // Add a default target if one wasn't specified. - if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) { + if (!HasTarget) { const char *DepTarget; // If user provided -o, that is the dependency target, except @@ -1108,17 +1131,14 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, DepTarget = Args.MakeArgString(llvm::sys::path::filename(P)); } - if (!A->getOption().matches(options::OPT_MD) && !A->getOption().matches(options::OPT_MMD)) { - CmdArgs.push_back("-w"); - } CmdArgs.push_back("-MT"); SmallString<128> Quoted; QuoteTarget(DepTarget, Quoted); CmdArgs.push_back(Args.MakeArgString(Quoted)); } - if (A->getOption().matches(options::OPT_M) || - A->getOption().matches(options::OPT_MD)) + if (ArgM->getOption().matches(options::OPT_M) || + ArgM->getOption().matches(options::OPT_MD)) CmdArgs.push_back("-sys-header-deps"); if ((isa(JA) && !Args.hasArg(options::OPT_fno_module_file_deps)) || @@ -1127,8 +1147,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, } if (Args.hasArg(options::OPT_MG)) { - if (!A || A->getOption().matches(options::OPT_MD) || - A->getOption().matches(options::OPT_MMD)) + if (!ArgM || ArgM->getOption().matches(options::OPT_MD) || + ArgM->getOption().matches(options::OPT_MMD)) D.Diag(diag::err_drv_mg_requires_m_or_mm); CmdArgs.push_back("-MG"); } @@ -1136,22 +1156,6 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_MP); Args.AddLastArg(CmdArgs, options::OPT_MV); - // Convert all -MQ args to -MT - for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) { - A->claim(); - - if (A->getOption().matches(options::OPT_MQ)) { - CmdArgs.push_back("-MT"); - SmallString<128> Quoted; - QuoteTarget(A->getValue(), Quoted); - CmdArgs.push_back(Args.MakeArgString(Quoted)); - - // -MT flag - no change - } else { - A->render(Args, CmdArgs); - } - } - // Add offload include arguments specific for CUDA. This must happen before // we -I or -include anything else, because we must pick up the CUDA headers // from the particular CUDA installation, rather than from e.g. diff --git a/clang/test/Driver/m-and-mm.c b/clang/test/Driver/m-and-mm.c index 6adcb86..cb719a6 100644 --- a/clang/test/Driver/m-and-mm.c +++ b/clang/test/Driver/m-and-mm.c @@ -1,16 +1,34 @@ -// RUN: %clang -M -MM %s 2>&1 | FileCheck /dev/null --implicit-check-not=warning +// RUN: %clang -M %s 2>&1 | FileCheck %s --implicit-check-not=warning +// RUN: %clang -MM %s 2>&1 | FileCheck %s --implicit-check-not=warning + +// CHECK: m-and-mm.o: +// TEST-I: {{.*}}test.i: +// TEST: {{.*}}test: // RUN: mkdir -p %t.dir + +/// if -MD and -MMD are not specified, -o specifies the dependency file name. +// RUN: rm -f %t.dir/test.i +// RUN: %clang -M %s -o %t.dir/test.i +// RUN: FileCheck %s < %t.dir/test.i +// RUN: rm -f %t.dir/test.i +// RUN: %clang -MM %s -o %t.dir/test.i +// RUN: FileCheck %s < %t.dir/test.i + // RUN: rm -f %t.dir/test.d // RUN: %clang -fsyntax-only -MD %s -o %t.dir/test.i -// RUN: test -f %t.dir/test.d +// RUN: FileCheck --check-prefix=TEST-I %s < %t.dir/test.d + +// RUN: rm -f %t.dir/test.d +// RUN: %clang -M -MD %s -o %t.dir/test.i +// RUN: FileCheck --check-prefix=TEST-I %s < %t.dir/test.d /// If the output file name does not have a suffix, just append `.d`. // RUN: rm -f %t.dir/test.d // RUN: %clang -fsyntax-only -MD %s -o %t.dir/test -// RUN: test -f %t.dir/test.d +// RUN: FileCheck --check-prefix=TEST %s < %t.dir/test.d -#warning "-M and -MM suppresses preprocessing, thus this warning shouldn't show up" +#warning "-M and -MM suppresses warnings, thus this warning shouldn't show up" int main(void) { return 0; -- 2.7.4