+ $link = 1;
+ }
+
+ # -MD/-MMD also cause dependency generation, but they don't imply -E!
+ if ($line =~ /\s(?:-MD|-MMD)\b/) {
+ $dependency = 0;
+ $flag_preprocess = 0;
+ }
+
+ # Dependency generation for Makefiles, no preprocessing or other flags
+ # needed.
+ next if $dependency;
+
+ # Get all file extensions on this line.
+ my @extensions = $line =~ /$file_extension_regex/go;
+ # Ignore all unknown extensions to speedup the search below.
+ @extensions = grep { exists $extension{$_} } @extensions;
+
+ # These file types don't require preprocessing.
+ if (extension_found(\%extensions_no_preprocess, @extensions)) {
+ $preprocess = 0;
+ }
+ # These file types require preprocessing.
+ if (extension_found(\%extensions_preprocess, @extensions)) {
+ $preprocess = 1;
+ }
+
+ if (not $flag_preprocess) {
+ # If there are source files then it's compiling/linking in one
+ # step and we must check both. We only check for source files
+ # here, because header files cause too many false positives.
+ if (extension_found(\%extensions_compile_link, @extensions)) {
+ # Assembly files don't need CFLAGS.
+ if (not extension_found(\%extensions_compile, @extensions)
+ and extension_found(\%extensions_no_compile, @extensions)) {
+ $compile = 0;
+ # But the rest does.
+ } else {
+ $compile = 1;
+ }
+ # No compilable extensions found, either linking or compiling
+ # header flags.
+ #
+ # If there are also no object files we are just compiling headers
+ # (.h -> .h.gch). Don't check for linker flags in this case. Due
+ # to our liberal checks for compiler lines, this also reduces the
+ # number of false positives considerably.
+ } elsif ($link
+ and not extension_found(\%extensions_object, @extensions)) {
+ $link = 0;
+ }
+ }
+
+ my $compile_cpp = 0;
+ my $compile_ada = 0;
+ # Assume CXXFLAGS are required when a C++ file is specified in the
+ # compiler line.
+ if ($compile
+ and extension_found(\%extensions_compile_cpp, @extensions)) {
+ $compile = 0;
+ $compile_cpp = 1;
+ # Ada needs special CFLAGS, use them if only ada files are compiled.
+ } elsif ($ada
+ and $compile
+ and array_equal(\@extensions,
+ \@source_no_preprocess_compile_ada)) {
+ $compile_ada = 1;
+ @cflags_backup = @cflags;
+ @cflags = @cflags_ada;
+ }
+
+ if ($option_buildd) {
+ $statistics{preprocess}++ if $preprocess;
+ $statistics{compile}++ if $compile;
+ $statistics{compile_cpp}++ if $compile_cpp;
+ $statistics{link}++ if $link;
+ }
+
+ # Check if there are flags indicating a debug build. If that's true,
+ # skip the check for -O2. This prevents fortification, but that's fine
+ # for a debug build.
+ if (any_flags_used($line, @def_cflags_debug)) {
+ remove_flags([\@cflags], \%flag_renames, $def_cflags[1]);
+ }
+
+ # Check hardening flags.
+ my @missing;
+ if ($compile 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, @def_cflags_pie)
+ # Assume dpkg-buildflags returns the correct flags.
+ and index($line, '`dpkg-buildflags --get CFLAGS`') == -1) {
+ if (not $option_buildd) {
+ error_flags('CFLAGS missing', \@missing, \%flag_renames, $input[$i]);
+ $exit |= $exit_code{flags_missing};
+ } else {
+ $statistics{compile_missing}++;
+ }
+ } 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, @def_cflags_pie)
+ # Assume dpkg-buildflags returns the correct flags.
+ and index($line, '`dpkg-buildflags --get CXXFLAGS`') == -1) {
+ if (not $option_buildd) {
+ error_flags('CXXFLAGS missing', \@missing, \%flag_renames, $input[$i]);
+ $exit |= $exit_code{flags_missing};
+ } else {
+ $statistics{compile_cpp_missing}++;
+ }
+ }
+ if ($preprocess
+ and (not all_flags_used($line, \@missing, @cppflags)
+ # The fortify flag might be overwritten, detect that.
+ or ($harden_fortify
+ and cppflags_fortify_broken($line, \@missing)))
+ # Assume dpkg-buildflags returns the correct flags.
+ and index($line, '`dpkg-buildflags --get CPPFLAGS`') == -1) {
+ if (not $option_buildd) {
+ error_flags('CPPFLAGS missing', \@missing, \%flag_renames, $input[$i]);
+ $exit |= $exit_code{flags_missing};
+ } else {
+ $statistics{preprocess_missing}++;
+ }
+ }
+ if ($link and not all_flags_used($line, \@missing, @ldflags)
+ # Same here, -fPIC conflicts with -fPIE.
+ and not pic_pie_conflict($line, $harden_pie, \@missing, @def_ldflags_pie)
+ # Assume dpkg-buildflags returns the correct flags.
+ and index($line, '`dpkg-buildflags --get LDFLAGS`') == -1) {
+ if (not $option_buildd) {
+ error_flags('LDFLAGS missing', \@missing, \%flag_renames, $input[$i]);
+ $exit |= $exit_code{flags_missing};
+ } else {
+ $statistics{link_missing}++;
+ }
+ }
+
+ # Restore normal CFLAGS.
+ if ($compile_ada) {
+ @cflags = @cflags_backup;