Author: Fangrui Song Date: 2024-05-07T09:15:52-07:00 New Revision: e74a7a9fd79a74073277471243a44527c71eb4a9
URL: https://github.com/llvm/llvm-project/commit/e74a7a9fd79a74073277471243a44527c71eb4a9 DIFF: https://github.com/llvm/llvm-project/commit/e74a7a9fd79a74073277471243a44527c71eb4a9.diff LOG: cc1: Report an error for multiple actions unless separated by -main-file-name (#91140) When multiple actions are specified, the last one is used and others are overridden. This might lead to confusion if the user is used to driver's `-S -emit-llvm` behavior. ``` %clang_cc1 -S -emit-llvm a.c # -S is overridden %clang_cc1 -emit-llvm -S a.c # -emit-llvm is overridden %clang_cc1 -fsyntax-only -S a.c # -fsyntax-only is overridden ``` However, we want to continue supporting overriding the driver action with -Xclang: * `clang -c -Xclang -ast-dump a.c` (`%clang -cc1 -emit-obj ... -main-file-name a.c ... -ast-dump`) * `clang -c -xc++ -Xclang -emit-module stl.modulemap` As an exception, we allow -ast-dump* options to be composed together (e.g. `-ast-dump -ast-dump-lookups` in AST/ast-dump-lookups.cpp). Added: clang/test/Frontend/multiple-actions.c Modified: clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/lib/Frontend/CompilerInvocation.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index fcffadacc8e631..e456ec2cac461c 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error< "no suitable precompiled header file found in directory '%0'">; def err_fe_action_not_available : Error< "action %0 not compiled in">; +def err_fe_invalid_multiple_actions : Error< + "'%0' action ignored; '%1' action specified previously">; def err_fe_invalid_alignment : Error< "invalid value '%1' in '%0'; alignment must be a power of 2">; def err_fe_invalid_exception_model diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 8312abc3603953..948fe08c863a66 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2841,6 +2841,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.ProgramAction = *ProgramAction; + + // Catch common mistakes when multiple actions are specified for cc1 (e.g. + // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to + // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name + // X ACTION), we suppress the error when the two actions are separated by + // -main-file-name. + // + // As an exception, accept composable -ast-dump*. + if (!A->getSpelling().starts_with("-ast-dump")) { + const Arg *SavedAction = nullptr; + for (const Arg *AA : + Args.filtered(OPT_Action_Group, OPT_main_file_name)) { + if (AA->getOption().matches(OPT_main_file_name)) { + SavedAction = nullptr; + } else if (!SavedAction) { + SavedAction = AA; + } else { + if (!A->getOption().matches(OPT_ast_dump_EQ)) + Diags.Report(diag::err_fe_invalid_multiple_actions) + << SavedAction->getSpelling() << A->getSpelling(); + break; + } + } + } } if (const Arg* A = Args.getLastArg(OPT_plugin)) { diff --git a/clang/test/Frontend/multiple-actions.c b/clang/test/Frontend/multiple-actions.c new file mode 100644 index 00000000000000..284e8f0467bfe1 --- /dev/null +++ b/clang/test/Frontend/multiple-actions.c @@ -0,0 +1,7 @@ +// RUN: not %clang_cc1 -S -emit-llvm -main-file-name %s 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error: +// ERR1: error: '-S' action ignored; '-emit-llvm' action specified previously + +// RUN: not %clang_cc1 -main-file-name %s -emit-llvm-only -emit-llvm -S 2>&1 | FileCheck %s --check-prefix=ERR2 --implicit-check-not=error: +// ERR2: error: '-emit-llvm-only' action ignored; '-S' action specified previously + +// RUN: %clang_cc1 -S -main-file-name %s -emit-llvm -o /dev/null _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits