Skip to content

Commit e74a7a9

Browse files
authored
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).
1 parent f00f294 commit e74a7a9

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error<
134134
"no suitable precompiled header file found in directory '%0'">;
135135
def err_fe_action_not_available : Error<
136136
"action %0 not compiled in">;
137+
def err_fe_invalid_multiple_actions : Error<
138+
"'%0' action ignored; '%1' action specified previously">;
137139
def err_fe_invalid_alignment : Error<
138140
"invalid value '%1' in '%0'; alignment must be a power of 2">;
139141
def err_fe_invalid_exception_model

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
28412841
}
28422842

28432843
Opts.ProgramAction = *ProgramAction;
2844+
2845+
// Catch common mistakes when multiple actions are specified for cc1 (e.g.
2846+
// -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
2847+
// support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
2848+
// X ACTION), we suppress the error when the two actions are separated by
2849+
// -main-file-name.
2850+
//
2851+
// As an exception, accept composable -ast-dump*.
2852+
if (!A->getSpelling().starts_with("-ast-dump")) {
2853+
const Arg *SavedAction = nullptr;
2854+
for (const Arg *AA :
2855+
Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
2856+
if (AA->getOption().matches(OPT_main_file_name)) {
2857+
SavedAction = nullptr;
2858+
} else if (!SavedAction) {
2859+
SavedAction = AA;
2860+
} else {
2861+
if (!A->getOption().matches(OPT_ast_dump_EQ))
2862+
Diags.Report(diag::err_fe_invalid_multiple_actions)
2863+
<< SavedAction->getSpelling() << A->getSpelling();
2864+
break;
2865+
}
2866+
}
2867+
}
28442868
}
28452869

28462870
if (const Arg* A = Args.getLastArg(OPT_plugin)) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: not %clang_cc1 -S -emit-llvm -main-file-name %s 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error:
2+
// ERR1: error: '-S' action ignored; '-emit-llvm' action specified previously
3+
4+
// 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:
5+
// ERR2: error: '-emit-llvm-only' action ignored; '-S' action specified previously
6+
7+
// RUN: %clang_cc1 -S -main-file-name %s -emit-llvm -o /dev/null

0 commit comments

Comments
 (0)