• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/cast.gni")
6import("//build/config/chrome_build.gni")
7import("//build/config/clang/clang.gni")
8import("//build/config/rust.gni")
9import("//build/config/sanitizers/sanitizers.gni")
10import("//build/toolchain/toolchain.gni")
11import("//build_overrides/build.gni")
12
13if (is_ios) {
14  import("//build/config/ios/ios_sdk.gni")
15}
16
17# libfuzzer can't cope with shared objects being unloaded, which sometimes
18# occurs for large fuzzers that involve our graphics stack. Shim out dlclose
19# so that this doesn't occur. At the moment we've only implemented this on Linux
20# since that's the only platform we use these large fuzzers - in the future
21# we could choose to do the same on Windows.
22use_dlcloseshim = use_libfuzzer && is_linux
23
24# Contains the dependencies needed for sanitizers to link into executables and
25# shared_libraries.
26group("deps") {
27  deps = []
28  if (using_sanitizer) {
29    public_configs = [
30      # Even when a target removes default_sanitizer_flags, it may be depending
31      # on a library that did not remove default_sanitizer_flags. Thus, we need
32      # to add the ldflags here as well as in default_sanitizer_flags.
33      ":default_sanitizer_ldflags",
34    ]
35    if (!is_fuchsia) {
36      if (is_win) {
37        exe = ".exe"
38      } else {
39        exe = ""
40      }
41      data = [
42        "//tools/valgrind/asan/",
43        "$clang_base_path/bin/llvm-symbolizer${exe}",
44      ]
45    }
46    if (is_asan || is_lsan || is_msan || is_tsan || is_ubsan || is_ubsan_vptr ||
47        is_ubsan_security) {
48      public_configs += [ ":sanitizer_options_link_helper" ]
49      deps += [ ":options_sources" ]
50    }
51    if (use_prebuilt_instrumented_libraries ||
52        use_locally_built_instrumented_libraries) {
53      deps += [ "//third_party/instrumented_libs:deps" ]
54    }
55  }
56  if (fail_on_san_warnings) {
57    data += [ "//tools/memory/sanitizer/escalate_sanitizer_warnings.py" ]
58  }
59  if (is_asan || is_ubsan || is_ubsan_vptr || is_ubsan_security) {
60    if ((is_win && is_component_build) || is_apple) {
61      data_deps = [ ":copy_sanitizer_runtime" ]
62    }
63    if (is_apple) {
64      public_deps = [ ":sanitizer_runtime_bundle_data" ]
65    }
66  }
67  if (use_centipede || enable_fuzztest_fuzz) {
68    # For executables which aren't actual fuzzers, we need stubs for
69    # the sanitizer coverage symbols, because we'll still be generating
70    # .o files which depend on them.
71    deps += [ "//third_party/fuzztest:centipede_weak_sancov_stubs" ]
72  }
73}
74
75assert(!(is_win && is_asan && current_cpu == "x86"),
76       "ASan is only supported in 64-bit builds on Windows.")
77
78if ((is_apple || (is_win && is_component_build)) &&
79    (is_asan || is_ubsan || is_ubsan_vptr || is_ubsan_security)) {
80  if (is_mac || (is_ios && target_environment == "catalyst")) {
81    if (is_asan) {
82      _clang_rt_dso_path = "darwin/libclang_rt.asan_osx_dynamic.dylib"
83    } else {
84      assert(is_ubsan || is_ubsan_vptr || is_ubsan_security)
85      _clang_rt_dso_path = "darwin/libclang_rt.ubsan_osx_dynamic.dylib"
86    }
87  } else if (is_ios) {
88    if (is_asan) {
89      _clang_rt_dso_path = "darwin/libclang_rt.asan_iossim_dynamic.dylib"
90    } else {
91      assert(is_ubsan || is_ubsan_vptr || is_ubsan_security)
92      _clang_rt_dso_path = "darwin/libclang_rt.ubsan_iossim_dynamic.dylib"
93    }
94  } else if (is_win && current_cpu == "x64" && is_component_build) {
95    if (is_asan) {
96      _clang_rt_dso_path = "windows/clang_rt.asan_dynamic-x86_64.dll"
97    } else {
98      assert(is_ubsan || is_ubsan_vptr || is_ubsan_security)
99      _clang_rt_dso_path = "windows/clang_rt.ubsan_dynamic-x86_64.dll"
100    }
101  }
102
103  _clang_rt_dso_full_path =
104      "$clang_base_path/lib/clang/$clang_version/lib/$_clang_rt_dso_path"
105
106  if (!is_ios) {
107    copy("copy_sanitizer_runtime") {
108      sources = [ _clang_rt_dso_full_path ]
109      outputs = [ "$root_out_dir/{{source_file_part}}" ]
110    }
111  } else {
112    # On iOS, the runtime library need to be code signed (adhoc signature)
113    # starting with Xcode 8, so use an action instead of a copy on iOS.
114    action("copy_sanitizer_runtime") {
115      script = "//build/config/ios/codesign.py"
116      sources = [ _clang_rt_dso_full_path ]
117      outputs = [ "$root_out_dir/" + get_path_info(sources[0], "file") ]
118      args = [
119        "code-sign-file",
120        "--identity=" + ios_code_signing_identity,
121        "--output=" + rebase_path(outputs[0], root_build_dir),
122        rebase_path(sources[0], root_build_dir),
123      ]
124    }
125  }
126
127  if (is_apple) {
128    bundle_data("sanitizer_runtime_bundle_data") {
129      sources = get_target_outputs(":copy_sanitizer_runtime")
130      outputs = [ "{{bundle_executable_dir}}/{{source_file_part}}" ]
131      public_deps = [ ":copy_sanitizer_runtime" ]
132    }
133  }
134}
135
136config("sanitizer_options_link_helper") {
137  if (is_apple) {
138    ldflags = [ "-Wl,-u,__sanitizer_options_link_helper" ]
139  } else if (!is_win) {
140    ldflags = [ "-Wl,-u_sanitizer_options_link_helper" ]
141  }
142}
143
144static_library("options_sources") {
145  # This is a static_library instead of a source_set, as it shouldn't be
146  # unconditionally linked into targets.
147  visibility = [
148    ":deps",
149    "//:gn_all",
150  ]
151  sources = [ "//build/sanitizers/sanitizer_options.cc" ]
152
153  # Don't compile this target with any sanitizer code. It can be called from
154  # the sanitizer runtimes, so instrumenting these functions could cause
155  # recursive calls into the runtime if there is an error.
156  configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
157
158  if (is_asan) {
159    if (!defined(asan_suppressions_file)) {
160      asan_suppressions_file = "//build/sanitizers/asan_suppressions.cc"
161    }
162    sources += [ asan_suppressions_file ]
163  }
164
165  if (is_lsan) {
166    if (!defined(lsan_suppressions_file)) {
167      lsan_suppressions_file = "//build/sanitizers/lsan_suppressions.cc"
168    }
169    sources += [ lsan_suppressions_file ]
170  }
171
172  if (is_tsan) {
173    if (!defined(tsan_suppressions_file)) {
174      tsan_suppressions_file = "//build/sanitizers/tsan_suppressions.cc"
175    }
176    sources += [ tsan_suppressions_file ]
177  }
178}
179
180if (use_dlcloseshim) {
181  source_set("dlclose_shim") {
182    sources = [ "//build/sanitizers/dlcloseshim.c" ]
183  }
184} else {
185  group("dlclose_shim") {
186    deps = []
187  }
188}
189
190# Applies linker flags necessary when either :deps or :default_sanitizer_flags
191# are used.
192config("default_sanitizer_ldflags") {
193  visibility = [
194    ":default_sanitizer_flags",
195    ":deps",
196
197    # https://crbug.com/360158.
198    "//tools/ipc_fuzzer/fuzzer:ipc_fuzzer",
199  ]
200
201  if (is_posix || is_fuchsia) {
202    sanitizers = []  # sanitizers applicable to both clang and rustc
203    ldflags = []
204    rustflags = []
205    if (is_asan) {
206      sanitizers += [ "address" ]
207    }
208    if (is_hwasan) {
209      sanitizers += [ "hwaddress" ]
210    }
211    if (is_lsan) {
212      # In Chromium, is_lsan always implies is_asan. ASAN includes LSAN.
213      # It seems harmless to pass both options to clang, but it doesn't
214      # work on rustc, so apply this option to clang only.
215      ldflags += [ "-fsanitize=leak" ]
216    }
217    if (is_tsan) {
218      sanitizers += [ "thread" ]
219    }
220    if (is_msan) {
221      sanitizers += [ "memory" ]
222    }
223    if (is_ubsan || is_ubsan_security) {
224      ldflags += [ "-fsanitize=undefined" ]
225    }
226    if (is_ubsan_vptr) {
227      ldflags += [ "-fsanitize=vptr" ]
228    }
229    foreach(sanitizer, sanitizers) {
230      ldflags += [ "-fsanitize=$sanitizer" ]
231      rustflags += [ "-Zsanitizer=$sanitizer" ]
232    }
233
234    if (use_sanitizer_coverage) {
235      if (use_libfuzzer) {
236        ldflags += [ "-fsanitize=fuzzer-no-link" ]
237        if (is_mac) {
238          # TODO(crbug.com/40611636): on macOS, dead code stripping does not work
239          # well with `pc-table` instrumentation enabled by `fuzzer-no-link`.
240          ldflags += [ "-fno-sanitize-coverage=pc-table" ]
241        }
242      } else {
243        ldflags += [ "-fsanitize-coverage=$sanitizer_coverage_flags" ]
244      }
245    }
246
247    if (is_cfi && current_toolchain == default_toolchain) {
248      ldflags += [ "-fsanitize=cfi-vcall" ]
249      if (use_cfi_cast) {
250        ldflags += [
251          "-fsanitize=cfi-derived-cast",
252          "-fsanitize=cfi-unrelated-cast",
253        ]
254      }
255      if (use_cfi_icall) {
256        ldflags += [ "-fsanitize=cfi-icall" ]
257      }
258      if (use_cfi_diag) {
259        ldflags += [ "-fno-sanitize-trap=cfi" ]
260        if (use_cfi_recover) {
261          ldflags += [ "-fsanitize-recover=cfi" ]
262        }
263      }
264    }
265  } else if (is_win) {
266    # Windows directly calls link.exe instead of the compiler driver when
267    # linking.  Hence, pass the runtime libraries instead of -fsanitize=address
268    # or -fsanitize=fuzzer.
269    if (is_asan && is_component_build) {
270      # In the static-library build, ASan libraries are different for
271      # executables and dlls, see link_executable and link_shared_library below.
272      # This here handles only the component build.
273      assert(current_cpu == "x64", "WinASan unsupported architecture")
274      libs = [
275        "clang_rt.asan_dynamic-x86_64.lib",
276        "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib",
277      ]
278    }
279    if (use_libfuzzer) {
280      assert(current_cpu == "x64", "LibFuzzer unsupported architecture")
281      assert(!is_component_build,
282             "LibFuzzer only supports non-component builds on Windows")
283
284      # Incremental linking causes padding that messes up SanitizerCoverage.
285      # Don't do it.
286      ldflags = [ "/INCREMENTAL:NO" ]
287    }
288  }
289  if (use_dlcloseshim) {
290    ldflags += [ "-Wl,-wrap,dlclose" ]
291  }
292}
293
294config("common_sanitizer_flags") {
295  cflags = []
296
297  if (using_sanitizer) {
298    assert(is_clang, "sanitizers only supported with clang")
299
300    # Allow non-default toolchains to enable sanitizers in toolchain_args even
301    # in official builds.
302    assert(current_toolchain != default_toolchain || !is_official_build,
303           "sanitizers not supported in official builds")
304
305    cflags += [
306      # Column info in debug data confuses Visual Studio's debugger, so don't
307      # use this by default.  However, clusterfuzz needs it for good
308      # attribution of reports to CLs, so turn it on there.
309      "-gcolumn-info",
310    ]
311
312    # Frame pointers are controlled in //build/config/compiler:default_stack_frames
313  }
314}
315
316config("asan_flags") {
317  cflags = []
318  if (is_asan) {
319    cflags += [ "-fsanitize=address" ]
320    if (!is_win && !is_apple && !is_fuchsia) {
321      # TODO(crbug.com/1459233, crbug.com/1462248): This causes asan
322      # odr-violation errors in rust code, and link failures for cros/asan.
323      # Clang recently turned it on by default for all ELF targets (it was
324      # already on for Fuchsia). Pass the flag to turn it back off.
325      cflags += [ "-fno-sanitize-address-globals-dead-stripping" ]
326    }
327    if (is_win) {
328      if (!defined(asan_win_blocklist_path)) {
329        asan_win_blocklist_path =
330            rebase_path("//tools/memory/asan/blocklist_win.txt", root_build_dir)
331      }
332      cflags += [ "-fsanitize-ignorelist=$asan_win_blocklist_path" ]
333    }
334  }
335}
336
337config("link_executable") {
338  if (is_asan && is_win && !is_component_build) {
339    assert(current_cpu == "x64", "WinASan unsupported architecture")
340    ldflags = [ "-wholearchive:clang_rt.asan-x86_64.lib" ]
341  }
342}
343
344config("link_shared_library") {
345  if (is_asan && is_win && !is_component_build) {
346    assert(current_cpu == "x64", "WinASan unsupported architecture")
347    libs = [ "clang_rt.asan_dll_thunk-x86_64.lib" ]
348  }
349}
350
351config("cfi_flags") {
352  cflags = []
353  rustflags = []
354  if (is_cfi && current_toolchain == default_toolchain) {
355    if (!defined(cfi_ignorelist_path)) {
356      cfi_ignorelist_path =
357          rebase_path("//tools/cfi/ignores.txt", root_build_dir)
358    }
359    cflags += [
360      "-fsanitize=cfi-vcall",
361      "-fsanitize-ignorelist=$cfi_ignorelist_path",
362    ]
363
364    if (toolchain_supports_rust_thin_lto) {
365      # sanitize=cfi implies -fsplit-lto-unit, and Rust needs to match
366      # behaviour.  Rust needs to know the linker will be doing LTO in this case
367      # or it rejects the Zsplit-lto-unit flag.
368      # TODO(crbug.com/40266913): Add -Zsanitize=cfi instead.
369      rustflags += [
370        "-Zsplit-lto-unit",
371        "-Clinker-plugin-lto=yes",
372      ]
373    } else {
374      # Don't include bitcode if it won't be used.
375      rustflags += [ "-Cembed-bitcode=no" ]
376    }
377
378    if (use_cfi_cast) {
379      cflags += [
380        "-fsanitize=cfi-derived-cast",
381        "-fsanitize=cfi-unrelated-cast",
382      ]
383    }
384
385    if (use_cfi_icall) {
386      cflags += [ "-fsanitize=cfi-icall" ]
387      # TODO(crbug.com/40266913): Add cflags += [
388      # "-fsanitize-cfi-icall-experimental-normalize-integers" ]
389      # TODO(crbug.com/40266913): Add rustflags += [
390      # "-Zsanitizer-cfi-normalize-integers" ].
391    }
392
393    if (use_cfi_diag) {
394      cflags += [ "-fno-sanitize-trap=cfi" ]
395      if (is_win) {
396        cflags += [
397          "/Oy-",
398          "/Ob0",
399        ]
400      } else {
401        cflags += [
402          "-fno-inline-functions",
403          "-fno-inline",
404          "-fno-omit-frame-pointer",
405          "-O1",
406        ]
407      }
408      if (use_cfi_recover) {
409        cflags += [ "-fsanitize-recover=cfi" ]
410      }
411    }
412  }
413}
414
415# crbug.com/785442: Fix cfi-icall failures for code that casts pointer argument
416# types in function pointer type signatures.
417config("cfi_icall_generalize_pointers") {
418  if (is_clang && is_cfi && use_cfi_icall) {
419    cflags = [ "-fsanitize-cfi-icall-generalize-pointers" ]
420  }
421}
422
423config("cfi_icall_disable") {
424  if (is_clang && is_cfi && use_cfi_icall) {
425    cflags = [ "-fno-sanitize=cfi-icall" ]
426  }
427}
428
429config("coverage_flags") {
430  cflags = []
431  if (use_sanitizer_coverage) {
432    # Used by sandboxing code to allow coverage dump to be written on the disk.
433    defines = [ "SANITIZER_COVERAGE" ]
434
435    if (use_libfuzzer) {
436      cflags += [ "-fsanitize=fuzzer-no-link" ]
437      if (is_mac) {
438        # TODO(crbug.com/40611636): on macOS, dead code stripping does not work
439        # well with `pc-table` instrumentation enabled by `fuzzer-no-link`.
440        cflags += [ "-fno-sanitize-coverage=pc-table" ]
441      }
442    } else {
443      cflags += [
444        "-fsanitize-coverage=$sanitizer_coverage_flags",
445        "-mllvm",
446        "-sanitizer-coverage-prune-blocks=1",
447      ]
448      if (current_cpu == "arm") {
449        # http://crbug.com/517105
450        cflags += [
451          "-mllvm",
452          "-sanitizer-coverage-block-threshold=0",
453        ]
454      }
455    }
456    if (sanitizer_coverage_allowlist != "") {
457      cflags += [ "-fsanitize-coverage-allowlist=" +
458                  rebase_path(sanitizer_coverage_allowlist, root_build_dir) ]
459    }
460  }
461  if (use_centipede) {
462    # Centipede intercepts calls such as memcmp and memcpy in order to improve
463    # its testcase generation.
464    cflags += [ "-fno-builtin" ]
465  }
466}
467
468config("hwasan_flags") {
469  if (is_hwasan) {
470    asmflags = [ "-fsanitize=hwaddress" ]
471    cflags = [ "-fsanitize=hwaddress" ]
472  }
473}
474
475config("lsan_flags") {
476  if (is_lsan) {
477    cflags = [ "-fsanitize=leak" ]
478  }
479}
480
481config("msan_flags") {
482  if (is_msan) {
483    assert(is_linux || is_chromeos,
484           "msan only supported on linux x86_64/ChromeOS")
485    if (!defined(msan_ignorelist_path)) {
486      msan_ignorelist_path =
487          rebase_path("//tools/msan/ignorelist.txt", root_build_dir)
488    }
489    cflags = [
490      "-fsanitize=memory",
491      "-fsanitize-memory-track-origins=$msan_track_origins",
492      "-fsanitize-ignorelist=$msan_ignorelist_path",
493    ]
494
495    if (!msan_check_use_after_dtor) {
496      # TODO(crbug.com/40222690): evaluate and possibly enable
497      cflags += [ "-fno-sanitize-memory-use-after-dtor" ]
498    }
499
500    if (!msan_eager_checks) {
501      cflags += [ "-fno-sanitize-memory-param-retval" ]
502    }
503  }
504}
505
506config("tsan_flags") {
507  if (is_tsan) {
508    assert(is_linux || is_chromeos, "tsan only supported on linux x86_64")
509    if (!defined(tsan_ignorelist_path)) {
510      tsan_ignorelist_path =
511          rebase_path("//tools/memory/tsan_v2/ignores.txt", root_build_dir)
512    }
513    cflags = [
514      "-fsanitize=thread",
515      "-fsanitize-ignorelist=$tsan_ignorelist_path",
516    ]
517  }
518}
519
520config("ubsan_flags") {
521  cflags = []
522  if (is_ubsan) {
523    if (!defined(ubsan_ignorelist_path)) {
524      ubsan_ignorelist_path =
525          rebase_path("//tools/ubsan/ignorelist.txt", root_build_dir)
526    }
527
528    # TODO(crbug.com/40942951): Enable all of -fsanitize=undefined. Note that
529    # both this list and Clang's defaults omit -fsanitize=float-divide-by-zero.
530    # C and C++ leave it undefined to accommodate non-IEEE floating point, but
531    # we assume the compiler implements IEEE floating point, which does define
532    # division by zero.
533    cflags += [
534      "-fsanitize=alignment",
535      "-fsanitize=bool",
536      "-fsanitize=bounds",
537      "-fsanitize=builtin",
538      "-fsanitize=integer-divide-by-zero",
539      "-fsanitize=null",
540      "-fsanitize=nonnull-attribute",
541      "-fsanitize=object-size",
542      "-fsanitize=return",
543      "-fsanitize=returns-nonnull-attribute",
544      "-fsanitize=shift",
545      "-fsanitize=signed-integer-overflow",
546      "-fsanitize=unreachable",
547      "-fsanitize=vla-bound",
548      "-fsanitize-ignorelist=$ubsan_ignorelist_path",
549    ]
550  }
551}
552
553config("ubsan_no_recover") {
554  if (is_ubsan_no_recover) {
555    cflags = [ "-fno-sanitize-recover=undefined" ]
556  }
557}
558
559config("ubsan_security_flags") {
560  if (is_ubsan_security) {
561    if (!defined(ubsan_security_ignorelist_path)) {
562      ubsan_security_ignorelist_path =
563          rebase_path("//tools/ubsan/security_ignorelist.txt", root_build_dir)
564    }
565    cflags = [
566      "-fsanitize=function",
567      "-fsanitize=shift",
568      "-fsanitize=signed-integer-overflow",
569      "-fsanitize=vla-bound",
570      "-fsanitize-ignorelist=$ubsan_security_ignorelist_path",
571    ]
572  }
573}
574
575config("ubsan_vptr_flags") {
576  if (is_ubsan_vptr) {
577    if (!defined(ubsan_vptr_ignorelist_path)) {
578      ubsan_vptr_ignorelist_path =
579          rebase_path("//tools/ubsan/vptr_ignorelist.txt", root_build_dir)
580    }
581    cflags = [
582      "-fsanitize=vptr",
583      "-fsanitize-ignorelist=$ubsan_vptr_ignorelist_path",
584    ]
585  }
586}
587
588config("fuzzing_build_mode") {
589  if (use_fuzzing_engine) {
590    defines = [ "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" ]
591  }
592}
593
594all_sanitizer_configs = [
595  ":common_sanitizer_flags",
596  ":coverage_flags",
597  ":default_sanitizer_ldflags",
598  ":asan_flags",
599  ":cfi_flags",
600  ":hwasan_flags",
601  ":lsan_flags",
602  ":msan_flags",
603  ":tsan_flags",
604  ":ubsan_flags",
605  ":ubsan_no_recover",
606  ":ubsan_security_flags",
607  ":ubsan_vptr_flags",
608  ":fuzzing_build_mode",
609]
610
611# This config is applied by default to all targets. It sets the compiler flags
612# for sanitizer usage, or, if no sanitizer is set, does nothing.
613#
614# This needs to be in a separate config so that targets can opt out of
615# sanitizers (by removing the config) if they desire. Even if a target
616# removes this config, executables & shared libraries should still depend on
617# :deps if any of their dependencies have not opted out of sanitizers.
618# Keep this list in sync with default_sanitizer_flags_but_ubsan_vptr.
619config("default_sanitizer_flags") {
620  configs = all_sanitizer_configs
621
622  if (use_sanitizer_configs_without_instrumentation) {
623    configs = []
624  }
625}
626
627# This config is equivalent to default_sanitizer_flags, but excludes ubsan_vptr.
628# This allows to selectively disable ubsan_vptr, when needed. In particular,
629# if some third_party code is required to be compiled without rtti, which
630# is a requirement for ubsan_vptr.
631config("default_sanitizer_flags_but_ubsan_vptr") {
632  configs = all_sanitizer_configs - [ ":ubsan_vptr_flags" ]
633
634  if (use_sanitizer_configs_without_instrumentation) {
635    configs = []
636  }
637}
638
639config("default_sanitizer_flags_but_coverage") {
640  configs = all_sanitizer_configs - [ ":coverage_flags" ]
641
642  if (use_sanitizer_configs_without_instrumentation) {
643    configs = []
644  }
645}
646
647# This config is used by parts of code that aren't targeted in fuzzers and
648# therefore don't need coverage instrumentation and possibly wont need
649# sanitizer instrumentation either. The config also tells the compiler to
650# perform additional optimizations on the configured code and ensures that
651# linking it to the rest of the binary which is instrumented with sanitizers
652# works. The config only does anything if the build is a fuzzing build.
653config("not_fuzzed") {
654  if (use_fuzzing_engine) {
655    # Since we aren't instrumenting with coverage, code size is less of a
656    # concern, so use a more aggressive optimization level than
657    # optimize_for_fuzzing (-O1). When given multiple optimization flags, clang
658    # obeys the last one, so as long as this flag comes after -O1, it should work.
659    # Since this config will always be depended on after
660    # "//build/config/compiler:default_optimization" (which adds -O1 when
661    # optimize_for_fuzzing is true), -O2 should always be the second flag. Even
662    # though this sounds fragile, it isn't a big deal if it breaks, since proto
663    # fuzzers will still work, they will just be slightly slower.
664    cflags = [ "-O2" ]
665
666    # We need to include this config when we remove default_sanitizer_flags or
667    # else there will be linking errors. We would remove default_sanitizer_flags
668    # here as well, but gn doesn't permit this.
669    if (!is_msan) {
670      # We don't actually remove sanitization when MSan is being used so there
671      # is no need to add default_sanitizer_ldflags in that case
672      configs = [ ":default_sanitizer_ldflags" ]
673    }
674  }
675}
676