my $warning_regex = qr/^(.+?):([0-9]+):[0-9]+: warning: (.+?) \[(.+?)\]$/;
# Regex for source files which require preprocessing.
+my $source_preprocess_compile_cpp_regex = qr/
+ # C++
+ cc | cp | cxx | cpp | CPP | c\+\+ | C
+ # Objective-C++
+ | mm | M
+ /x;
my $source_preprocess_compile_regex = qr/
# C
c
# Objective-C
| m
- # C++
- | cc | cp | cxx | cpp | CPP | c\+\+ | C
- # Objective-C++
- | mm | M
+ # (Objective-)C++
+ | $source_preprocess_compile_cpp_regex
# Fortran
| F | FOR | fpp | FPP | FTN | F90 | F95 | F03 | F08
/x;
| $source_preprocess_no_compile_regex
/x;
# Regex for source files which don't require preprocessing.
+my $source_no_preprocess_compile_cpp_regex = qr/
+ # C++
+ ii
+ # Objective-C++
+ | mii
+ /x;
my $source_no_preprocess_compile_regex = qr/
# C
i
- # C++
- | ii
+ # (Objective-)C++
+ | $source_no_preprocess_compile_cpp_regex
# Objective-C
| mi
- # Objective-C++
- | mii
# Fortran
| f | for | ftn | f90 | f95 | f03 | f08
/x;
\.(?: $source_preprocess_no_compile_regex
| $source_no_preprocess_no_compile_regex)\b
/x;
+my $file_compile_cpp_regex = qr/
+ $cc_regex.+
+ \.(?: $source_preprocess_compile_cpp_regex
+ | $source_no_preprocess_compile_cpp_regex)\b
+ /x;
# Expected (hardening) flags. All flags are used as regexps.
my @cflags = (
my @cflags_pie = (
'-fPIE',
);
+my @cxxflags = (
+ '-g',
+ '-O(?:2|3)',
+);
+# @cxxflags_* is the same as @cflags_*.
my @cppflags = ();
my @cppflags_fortify = (
'-D_FORTIFY_SOURCE=2',
# Check the specified hardening options, same order as dpkg-buildflags.
if ($harden_pie) {
@cflags = (@cflags, @cflags_pie);
+ @cxxflags = (@cxxflags, @cflags_pie);
@ldflags = (@ldflags, @ldflags_pie);
}
if ($harden_stack) {
@cflags = (@cflags, @cflags_stack);
+ @cxxflags = (@cxxflags, @cflags_stack);
}
if ($harden_fortify) {
@cflags = (@cflags, @cflags_fortify);
+ @cxxflags = (@cxxflags, @cflags_fortify);
@cppflags = (@cppflags, @cppflags_fortify);
}
if ($harden_format) {
@cflags = (@cflags, @cflags_format);
+ @cxxflags = (@cxxflags, @cflags_format);
}
if ($harden_relro) {
@ldflags = (@ldflags, @ldflags_relro);
}
}
+ # Assume CXXFLAGS are required when a C++ file is specified in the
+ # compiler line.
+ my $compile_cpp = 0;
+ if ($compile and $line =~ /$file_compile_cpp_regex/) {
+ $compile = 0;
+ $compile_cpp = 1;
+ }
+
# Check hardening flags.
my @missing;
if ($compile and not all_flags_used($line, \@missing, @cflags)
# with -fPIE as well. It's no error if only PIE flags are missing.
and not pic_pie_conflict($line, $harden_pie, \@missing, @cflags_pie)
# Assume dpkg-buildflags returns the correct flags.
- and not $line =~ /`dpkg-buildflags --get (?:CFLAGS|CXXFLAGS)`/) {
+ and not $line =~ /`dpkg-buildflags --get CFLAGS`/) {
error_flags('CFLAGS missing', \@missing, \%flag_renames, $line);
$exit |= 1 << 3;
+ } elsif ($compile_cpp and not all_flags_used($line, \@missing, @cflags)
+ # Libraries linked with -fPIC don't have to (and can't) be linked
+ # with -fPIE as well. It's no error if only PIE flags are missing.
+ and not pic_pie_conflict($line, $harden_pie, \@missing, @cflags_pie)
+ # Assume dpkg-buildflags returns the correct flags.
+ and not $line =~ /`dpkg-buildflags --get CXXFLAGS`/) {
+ error_flags('CXXFLAGS missing', \@missing, \%flag_renames, $line);
+ $exit |= 1 << 3;
}
if ($preprocess and not all_flags_used($line, \@missing, @cppflags)
# Assume dpkg-buildflags returns the correct flags.