Skip to content

Commit a9783b7

Browse files
mistmistemabrey
authored andcommitted
GCC: suppress rewrite_includes_only with pedantic flags (mozilla#1123)
* GCC: suppress rewrite_includes_only with pedantic flags CoinMP/CoinUtils configure checks the <cmath> header: configure:9903: sccache g++ -c -O3 -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long -DCOINUTILS_BUILD conftest.cc >&5 <built-in>: error: ISO C++ does not support '__int128' for '__x' [-Wpedantic] <built-in>: error: ISO C++ does not support '__int128' for 'abs' [-Wpedantic] In file included from /usr/include/c++/10/cmath:42, from conftest.cc:64: <built-in>: error: ISO C++ does not support '__int128' for 'type name' [-Wpedantic] The problem is that in GCC 10, the bits/std_abs.h declares abs() for GCC extension __int128, which -pedantic then complains about. Implement the same solution that icecream has for this problem: for GCC, if any -pedantic etc. flag is given and GNU extensions are enabled, don't use -fdirectives-only. * GCC: add test for suppress rewrite_includes_only with pedantic flags Requires refactoring the preprocess() a bit so that the generated arguments can be inspected by a test.
1 parent 934d55b commit a9783b7

File tree

6 files changed

+157
-20
lines changed

6 files changed

+157
-20
lines changed

src/compiler/c.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ pub struct ParsedArguments {
9696
pub profile_generate: bool,
9797
/// The color mode.
9898
pub color_mode: ColorMode,
99+
/// arguments are incompatible with rewrite_includes_only
100+
pub suppress_rewrite_includes_only: bool,
99101
}
100102

101103
impl ParsedArguments {

src/compiler/clang.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl CCompilerImpl for Clang {
5555
cwd,
5656
(&gcc::ARGS[..], &ARGS[..]),
5757
self.clangplusplus,
58+
self.kind(),
5859
)
5960
}
6061

src/compiler/diab.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ where
283283
profile_generate: false,
284284
// FIXME: Implement me.
285285
color_mode: ColorMode::Auto,
286+
suppress_rewrite_includes_only: false,
286287
})
287288
}
288289

@@ -681,6 +682,7 @@ mod test {
681682
msvc_show_includes: false,
682683
profile_generate: false,
683684
color_mode: ColorMode::Auto,
685+
suppress_rewrite_includes_only: false,
684686
};
685687
let compiler = &f.bins[0];
686688
// Compiler invocation.

src/compiler/gcc.rs

Lines changed: 140 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl CCompilerImpl for Gcc {
4747
arguments: &[OsString],
4848
cwd: &Path,
4949
) -> CompilerArguments<ParsedArguments> {
50-
parse_arguments(arguments, cwd, &ARGS[..], self.gplusplus)
50+
parse_arguments(arguments, cwd, &ARGS[..], self.gplusplus, self.kind())
5151
}
5252

5353
#[allow(clippy::too_many_arguments)]
@@ -129,6 +129,8 @@ ArgData! { pub
129129
// Only valid for clang, but this needs to be here since clang shares gcc's arg parsing.
130130
XClang(OsString),
131131
Arch(OsString),
132+
PedanticFlag,
133+
Standard(OsString),
132134
}
133135

134136
use self::ArgData::*;
@@ -160,6 +162,8 @@ counted_array!(pub static ARGS: [ArgInfo<ArgData>; _] = [
160162
flag!("-P", TooHardFlag),
161163
take_arg!("-U", OsString, CanBeSeparated, PassThrough),
162164
take_arg!("-V", OsString, Separated, PassThrough),
165+
flag!("-Werror=pedantic", PedanticFlag),
166+
flag!("-Wpedantic", PedanticFlag),
163167
take_arg!("-Xassembler", OsString, Separated, PassThrough),
164168
take_arg!("-Xlinker", OsString, Separated, PassThrough),
165169
take_arg!("-Xpreprocessor", OsString, Separated, PreprocessorArgument),
@@ -196,8 +200,11 @@ counted_array!(pub static ARGS: [ArgInfo<ArgData>; _] = [
196200
flag!("-nostdinc", PreprocessorArgumentFlag),
197201
flag!("-nostdinc++", PreprocessorArgumentFlag),
198202
take_arg!("-o", PathBuf, CanBeSeparated, Output),
203+
flag!("-pedantic", PedanticFlag),
204+
flag!("-pedantic-errors", PedanticFlag),
199205
flag!("-remap", PreprocessorArgumentFlag),
200206
flag!("-save-temps", TooHardFlag),
207+
take_arg!("-std", OsString, Concatenated('='), Standard),
201208
take_arg!("-stdlib", OsString, Concatenated('='), PreprocessorArgument),
202209
flag!("-trigraphs", PreprocessorArgumentFlag),
203210
take_arg!("-u", OsString, CanBeSeparated, PassThrough),
@@ -220,6 +227,7 @@ pub fn parse_arguments<S>(
220227
cwd: &Path,
221228
arg_info: S,
222229
plusplus: bool,
230+
kind: CCompilerKind,
223231
) -> CompilerArguments<ParsedArguments>
224232
where
225233
S: SearchableArgInfo<ArgData>,
@@ -234,6 +242,8 @@ where
234242
let mut extra_hash_files = vec![];
235243
let mut compilation = false;
236244
let mut multiple_input = false;
245+
let mut pedantic_flag = false;
246+
let mut language_extensions = true; // by default, GCC allows extensions
237247
let mut split_dwarf = false;
238248
let mut need_explicit_dep_target = false;
239249
let mut language = None;
@@ -274,6 +284,9 @@ where
274284
Some(TooHardFlag) | Some(TooHard(_)) => {
275285
cannot_cache!(arg.flag_str().expect("Can't be Argument::Raw/UnknownFlag",))
276286
}
287+
Some(PedanticFlag) => pedantic_flag = true,
288+
// standard values vary, but extension values all start with "gnu"
289+
Some(Standard(version)) => language_extensions = version.starts_with("gnu"),
277290
Some(SplitDwarf) => split_dwarf = true,
278291
Some(DoCompilation) => {
279292
compilation = true;
@@ -342,6 +355,8 @@ where
342355
}
343356
let args = match arg.get_data() {
344357
Some(SplitDwarf)
358+
| Some(PedanticFlag)
359+
| Some(Standard(_))
345360
| Some(ProfileGenerate)
346361
| Some(ClangProfileUse(_))
347362
| Some(TestCoverage)
@@ -386,6 +401,8 @@ where
386401
let arg = try_or_cannot_cache!(arg, "argument parse");
387402
let args = match arg.get_data() {
388403
Some(SplitDwarf)
404+
| Some(PedanticFlag)
405+
| Some(Standard(_))
389406
| Some(ProfileGenerate)
390407
| Some(ClangProfileUse(_))
391408
| Some(TestCoverage)
@@ -478,6 +495,10 @@ where
478495
let dwo = output.with_extension("dwo");
479496
outputs.insert("dwo", dwo);
480497
}
498+
let suppress_rewrite_includes_only = match kind {
499+
CCompilerKind::Gcc => language_extensions && pedantic_flag,
500+
_ => false,
501+
};
481502
if outputs_gcno {
482503
let gcno = output.with_extension("gcno");
483504
outputs.insert("gcno", gcno);
@@ -502,32 +523,29 @@ where
502523
msvc_show_includes: false,
503524
profile_generate,
504525
color_mode,
526+
suppress_rewrite_includes_only,
505527
})
506528
}
507529

508530
#[allow(clippy::too_many_arguments)]
509-
pub async fn preprocess<T>(
510-
creator: &T,
511-
executable: &Path,
531+
fn preprocess_cmd<T>(
532+
cmd: &mut T,
512533
parsed_args: &ParsedArguments,
513534
cwd: &Path,
514535
env_vars: &[(OsString, OsString)],
515536
may_dist: bool,
516537
kind: CCompilerKind,
517538
rewrite_includes_only: bool,
518-
) -> Result<process::Output>
519-
where
520-
T: CommandCreatorSync,
539+
) where
540+
T: RunCommand,
521541
{
522-
trace!("preprocess");
523542
let language = match parsed_args.language {
524543
Language::C => "c",
525544
Language::Cxx => "c++",
526545
Language::ObjectiveC => "objective-c",
527546
Language::ObjectiveCxx => "objective-c++",
528547
Language::Cuda => "cu",
529548
};
530-
let mut cmd = creator.clone().new_command_sync(executable);
531549
cmd.arg("-x").arg(language).arg("-E");
532550
// When performing distributed compilation, line number info is important for error
533551
// reporting and to not cause spurious compilation failure (e.g. no exceptions build
@@ -537,14 +555,20 @@ where
537555
cmd.arg("-P");
538556
}
539557
if rewrite_includes_only {
540-
match kind {
541-
CCompilerKind::Clang => {
542-
cmd.arg("-frewrite-includes");
558+
if parsed_args.suppress_rewrite_includes_only {
559+
if log_enabled!(Trace) {
560+
trace!("preprocess: pedantic arguments disable rewrite_includes_only");
543561
}
544-
CCompilerKind::Gcc => {
545-
cmd.arg("-fdirectives-only");
562+
} else {
563+
match kind {
564+
CCompilerKind::Clang => {
565+
cmd.arg("-frewrite-includes");
566+
}
567+
CCompilerKind::Gcc => {
568+
cmd.arg("-fdirectives-only");
569+
}
570+
_ => {}
546571
}
547-
_ => {}
548572
}
549573
}
550574
cmd.arg(&parsed_args.input)
@@ -554,7 +578,33 @@ where
554578
.env_clear()
555579
.envs(env_vars.iter().map(|&(ref k, ref v)| (k, v)))
556580
.current_dir(cwd);
581+
}
557582

583+
#[allow(clippy::too_many_arguments)]
584+
pub async fn preprocess<T>(
585+
creator: &T,
586+
executable: &Path,
587+
parsed_args: &ParsedArguments,
588+
cwd: &Path,
589+
env_vars: &[(OsString, OsString)],
590+
may_dist: bool,
591+
kind: CCompilerKind,
592+
rewrite_includes_only: bool,
593+
) -> Result<process::Output>
594+
where
595+
T: CommandCreatorSync,
596+
{
597+
trace!("preprocess");
598+
let mut cmd = creator.clone().new_command_sync(executable);
599+
preprocess_cmd(
600+
&mut cmd,
601+
parsed_args,
602+
cwd,
603+
env_vars,
604+
may_dist,
605+
kind,
606+
rewrite_includes_only,
607+
);
558608
if log_enabled!(Trace) {
559609
trace!("preprocess: {:?}", cmd);
560610
}
@@ -652,7 +702,7 @@ pub fn generate_compile_commands(
652702
// -fdirectives-only.
653703
//
654704
// Which is exactly what we do :-)
655-
if rewrite_includes_only {
705+
if rewrite_includes_only && !parsed_args.suppress_rewrite_includes_only {
656706
arguments.push("-fdirectives-only".into());
657707
}
658708
arguments.push("-fpreprocessed".into());
@@ -753,7 +803,7 @@ mod test {
753803
plusplus: bool,
754804
) -> CompilerArguments<ParsedArguments> {
755805
let args = arguments.iter().map(OsString::from).collect::<Vec<_>>();
756-
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus)
806+
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus, CCompilerKind::Gcc)
757807
}
758808

759809
#[test]
@@ -1155,6 +1205,78 @@ mod test {
11551205
assert!(args.common_args.contains(&"-fdiagnostics-color".into()));
11561206
}
11571207

1208+
#[test]
1209+
fn pedantic_default() {
1210+
let args = stringvec!["-pedantic", "-c", "foo.cc"];
1211+
let parsed_args = match parse_arguments_(args, false) {
1212+
CompilerArguments::Ok(args) => args,
1213+
o => panic!("Got unexpected parse result: {:?}", o),
1214+
};
1215+
let mut cmd = MockCommand {
1216+
child: None,
1217+
args: vec![],
1218+
};
1219+
preprocess_cmd(
1220+
&mut cmd,
1221+
&parsed_args,
1222+
Path::new(""),
1223+
&[],
1224+
true,
1225+
CCompilerKind::Gcc,
1226+
true,
1227+
);
1228+
// disable with extensions enabled
1229+
assert!(!cmd.args.contains(&"-fdirectives-only".into()));
1230+
}
1231+
1232+
#[test]
1233+
fn pedantic_std() {
1234+
let args = stringvec!["-pedantic-errors", "-c", "-std=c++14", "foo.cc"];
1235+
let parsed_args = match parse_arguments_(args, false) {
1236+
CompilerArguments::Ok(args) => args,
1237+
o => panic!("Got unexpected parse result: {:?}", o),
1238+
};
1239+
let mut cmd = MockCommand {
1240+
child: None,
1241+
args: vec![],
1242+
};
1243+
preprocess_cmd(
1244+
&mut cmd,
1245+
&parsed_args,
1246+
Path::new(""),
1247+
&[],
1248+
true,
1249+
CCompilerKind::Gcc,
1250+
true,
1251+
);
1252+
// no reason to disable it with no extensions enabled
1253+
assert!(cmd.args.contains(&"-fdirectives-only".into()));
1254+
}
1255+
1256+
#[test]
1257+
fn pedantic_gnu() {
1258+
let args = stringvec!["-pedantic-errors", "-c", "-std=gnu++14", "foo.cc"];
1259+
let parsed_args = match parse_arguments_(args, false) {
1260+
CompilerArguments::Ok(args) => args,
1261+
o => panic!("Got unexpected parse result: {:?}", o),
1262+
};
1263+
let mut cmd = MockCommand {
1264+
child: None,
1265+
args: vec![],
1266+
};
1267+
preprocess_cmd(
1268+
&mut cmd,
1269+
&parsed_args,
1270+
Path::new(""),
1271+
&[],
1272+
true,
1273+
CCompilerKind::Gcc,
1274+
true,
1275+
);
1276+
// disable with extensions enabled
1277+
assert!(!cmd.args.contains(&"-fdirectives-only".into()));
1278+
}
1279+
11581280
#[test]
11591281
fn test_parse_arguments_dep_target_needed() {
11601282
let args = stringvec!["-c", "foo.c", "-fabc", "-MF", "file", "-o", "foo.o", "-MD"];
@@ -1324,6 +1446,7 @@ mod test {
13241446
msvc_show_includes: false,
13251447
profile_generate: false,
13261448
color_mode: ColorMode::Auto,
1449+
suppress_rewrite_includes_only: false,
13271450
};
13281451
let compiler = &f.bins[0];
13291452
// Compiler invocation.

src/compiler/msvc.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,8 @@ pub fn parse_arguments(
584584
use crate::compiler::gcc::ArgData::*;
585585
let args = match arg.get_data() {
586586
Some(SplitDwarf) | Some(TestCoverage) | Some(Coverage) | Some(DoCompilation)
587-
| Some(Language(_)) | Some(Output(_)) | Some(TooHardFlag) | Some(XClang(_))
588-
| Some(TooHard(_)) => cannot_cache!(arg
587+
| Some(PedanticFlag) | Some(Standard(_)) | Some(Language(_)) | Some(Output(_))
588+
| Some(TooHardFlag) | Some(XClang(_)) | Some(TooHard(_)) => cannot_cache!(arg
589589
.flag_str()
590590
.unwrap_or("Can't handle complex arguments through clang",)),
591591
None => match arg {
@@ -687,6 +687,7 @@ pub fn parse_arguments(
687687
profile_generate,
688688
// FIXME: implement color_mode for msvc.
689689
color_mode: ColorMode::Auto,
690+
suppress_rewrite_includes_only: false,
690691
})
691692
}
692693

@@ -1348,6 +1349,7 @@ mod test {
13481349
msvc_show_includes: false,
13491350
profile_generate: false,
13501351
color_mode: ColorMode::Auto,
1352+
suppress_rewrite_includes_only: false,
13511353
};
13521354
let compiler = &f.bins[0];
13531355
// Compiler invocation.
@@ -1391,6 +1393,7 @@ mod test {
13911393
msvc_show_includes: false,
13921394
profile_generate: false,
13931395
color_mode: ColorMode::Auto,
1396+
suppress_rewrite_includes_only: false,
13941397
};
13951398
let compiler = &f.bins[0];
13961399
// Compiler invocation.

src/compiler/nvcc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ impl CCompilerImpl for Nvcc {
4848
arguments: &[OsString],
4949
cwd: &Path,
5050
) -> CompilerArguments<ParsedArguments> {
51-
gcc::parse_arguments(arguments, cwd, (&gcc::ARGS[..], &ARGS[..]), false)
51+
gcc::parse_arguments(
52+
arguments,
53+
cwd,
54+
(&gcc::ARGS[..], &ARGS[..]),
55+
false,
56+
self.kind(),
57+
)
5258
}
5359

5460
#[allow(clippy::too_many_arguments)]

0 commit comments

Comments
 (0)