Commit Graph

182 Commits

Author SHA1 Message Date
Teresa Johnson b55a964197 Second attempt to fix Windows failures from test changes
Try to address Windows flakes from d87bdc272b
by adding "|| true" as suggested in D110276 so the whole test doesn't
fail when Windows thinks it can't remove the binary.
2021-09-29 19:24:35 -07:00
Teresa Johnson 2f1b99ca67 Use rm -f to fix Windows failures from test changes
Try to address Windows flakes from d87bdc272b
by using 'rm -f' instead of just 'rm' as discussed in D110276. For example:
http://45.33.8.238/win/46115/step_7.txt
2021-09-29 08:01:22 -07:00
Teresa Johnson d87bdc272b Clean up large copies of binaries copied into temp directories in tests
In looking at the disk space used by a ninja check-all, I found that a
few of the largest files were copies of clang and lld made into temp
directories by a couple of tests. These tests were added in D53021 and
D74811. Clean up these copies after usage.

Differential Revision: https://reviews.llvm.org/D110276
2021-09-28 17:04:09 -07:00
Fangrui Song c38efb4899 [clang] Implement -falign-loops=N (N is a power of 2) for non-LTO
GCC supports multiple forms of -falign-loops=.
-falign-loops= is currently ignored in Clang.

This patch implements the simplest but the most useful form where N is a
power of 2.

The underlying implementation uses a `llvm::TargetOptions` option for now.
Bitcode generation ignores this option.

Differential Revision: https://reviews.llvm.org/D106701
2021-08-05 12:17:50 -07:00
Aaron Ballman 530ea28fef Correct a lot of diagnostic wordings for the driver
Clang diagnostics should not start with a capital letter or use
trailing punctuation (https://clang.llvm.org/docs/InternalsManual.html#the-format-string),
but quite a few driver diagnostics were not following this advice. This
corrects the grammar and punctuation to improve consistency, but does
not change the circumstances under which the diagnostics are produced.
2021-08-05 07:04:55 -04:00
Melanie Blower e773216f46 [clang][patch] Add builtin __arithmetic_fence and option fprotect-parens
This patch adds a new clang builtin, __arithmetic_fence. The purpose of the
builtin is to provide the user fine control, at the expression level, over
floating point optimization when -ffast-math (-ffp-model=fast) is enabled.
The builtin prevents the optimizer from rearranging floating point expression
evaluation. The new option fprotect-parens has the same effect on
parenthesized expressions, forcing the optimizer to respect the parentheses.

Reviewed By: aaron.ballman, kpn

Differential Revision: https://reviews.llvm.org/D100118
2021-06-30 09:58:06 -04:00
Melanie Blower c27e5a2a8e Revert "[clang][patch][fpenv] Add builtin __arithmetic_fence and option fprotect-parens"
This reverts commit 4f1238e44d.
Buildbot fails on predecessor patch
2021-06-28 12:42:59 -04:00
Melanie Blower 4f1238e44d [clang][patch][fpenv] Add builtin __arithmetic_fence and option fprotect-parens
This patch adds a new clang builtin, __arithmetic_fence. The purpose of the
builtin is to provide the user fine control, at the expression level, over
floating point optimization when -ffast-math (-ffp-model=fast) is enabled.
The builtin prevents the optimizer from rearranging floating point expression
evaluation. The new option fprotect-parens has the same effect on
parenthesized expressions, forcing the optimizer to respect the parentheses.

Reviewed By: aaron.ballman, kpn

Differential Revision: https://reviews.llvm.org/D100118
2021-06-28 12:26:53 -04:00
Jinsong Ji 82b5281247 [Driver][test] Don't assume integrated-as
The tests of fdebug-compilation-dir and -ffile-compilation-dir for `-x
assembler` are assuming integrated-as.
If the platform set the no-itegrated-as by default (eg: AIX for now), then this test will
fail.

Add the -integrated-as to aviod relying on the platform defaults.

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D102647
2021-05-17 20:24:21 +00:00
Artem Belevich eaa9ef075d [CUDA, FDO] Filter out profiling options from GPU-side compilations.
Differential Revision: https://reviews.llvm.org/D100598
2021-04-16 11:35:28 -07:00
Matthias Klose 56cb214b38 add test case for ignoring -flto=auto and -flto=jobserver
as requested in https://reviews.llvm.org/D99501, test that the two new options are ignored.

Reviewed By: tejohnson, fhahn

Differential Revision: https://reviews.llvm.org/D100484
2021-04-15 12:19:14 +02:00
Erik Pilkington b660abc80d [ObjC] Add a command line flag that disables recognition of objc_direct for testability
Programmers would like to be able to test direct methods by calling them from a
different linkage unit or mocking them, both of which are impossible. This
patch adds a flag that effectively disables the attribute, which will fix this
when enabled in testable builds. rdar://71190891

Differential revision: https://reviews.llvm.org/D95845
2021-04-06 11:17:01 -04:00
Chuanqi Xu 20b4f484d1 [Driver] Add -fno-split-stack
Summary: Add -fno-split-stack and rename CC1 option from `-split-stacks`
to `-fsplit-stack`.

Test Plan: check-all

Differential Revision: https://reviews.llvm.org/D99245
2021-03-25 14:18:28 +08:00
Petr Hosek bf6380c096 [Driver] Don't pass -ffile-compilation-dir through to cc1
This is a driver only flag so it has to be expanded when invoking cc1.

Differential Revision: https://reviews.llvm.org/D97528
2021-02-25 23:03:54 -08:00
Petr Hosek 9e56a093ee [Driver] Create -ffile-compilation-dir alias
We introduce -ffile-compilation-dir shorthand to avoid having to set
-fdebug-compilation-dir and -fprofile-compilation-dir separately. This
is similar to -ffile-prefix-map.

Differential Revision: https://reviews.llvm.org/D97433
2021-02-25 21:20:10 -08:00
Fangrui Song 0c2bb6b446 [Driver] Clean up some Separate form options
Drop the `Separate` form of `-fmodule-name X`, `-fprofile-remapping-file X`, and `-frewrite-map-file X`.
To the best of my knowledge they are not used. Their conventional Joined forms (`-fFOO=`) should be used instead.

`-fdebug-compilation-dir X` is used in several places, e.g.  chromium/infra/goma.
It is also advertised in http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
So we keep it but make the EQ form canonical and the Separate form an alias.

Differential Revision: https://reviews.llvm.org/D96886
2021-02-17 13:49:41 -08:00
Fangrui Song f9c0d1b056 [Driver] Add -f[no-]legacy-pass-manager to supersede -f[no-]experimental-new-pass-manager
The new PM is considered stable and many downstream groups have adopted it (some
have adopted it for more than two years). Add -f[no-]legacy-pass-manager to reflect the
fact that it is no longer experimental and the legacy pass manager is something we strive to retire.

In the future, when the legacy PM eventually goes away,
-fno-experimental-new-pass-manager and -flegacy-pass-manager will be removed.

This patch also changes -f[no-]legacy-pass-manager to pass `-plugin-opt={new,legacy}-pass-manager` to the linker (supported by both ld.lld and LLVMgold.so) when -flto/-flto=thin is specified

Reviewed By: aeubanks, rsmith

Differential Revision: https://reviews.llvm.org/D92915
2020-12-09 16:57:36 -08:00
Nico Weber e0e334a9c1 [mac/arm] make clang/test/Driver/clang_f_opts.c pass consistently
Part of PR46644, see comment 7/8.
2020-11-23 12:56:52 -05:00
Jian Cai 4db2b70248 Add a flag to debug automatic variable initialization
Summary:
Add -ftrivial-auto-var-init-stop-after= to limit the number of times
stack variables are initialized when -ftrivial-auto-var-init= is used to
initialize stack variables to zero or a pattern. This flag can be used
to bisect uninitialized uses of a stack variable exposed by automatic
variable initialization, such as http://crrev.com/c/2020401.

Reviewers: jfb, vitalybuka, kcc, glider, rsmith, rjmccall, pcc, eugenis, vlad.tsyrklevich

Reviewed By: jfb

Subscribers: phosek, hubert.reinterpretcast, srhines, MaskRay, george.burgess.iv, dexonsmith, inglorion, gbiv, llozano, manojgupta, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77168
2020-06-08 12:30:56 -07:00
Fangrui Song 82904401e3 Map -O to -O1 instead of -O2
rL82131 changed -O from -O1 to -O2, because -O1 was not different from
-O2 at that time.

GCC treats -O as -O1 and there is now work to make -O1 meaningful.
We can change -O back to -O1 again.

Reviewed By: echristo, dexonsmith, arphaman

Differential Revision: https://reviews.llvm.org/D79916
2020-05-18 15:53:41 -07:00
Fangrui Song e1815eb2e1 [Driver] Reorganize --coverage -ftest-coverage -fprofile-arcs related tests
And fix a comment about __llvm_profile_runtime
2020-05-08 16:06:33 -07:00
Fangrui Song a1e940b185 [Driver][test] Add a specific test file for -fmerge-all-constants
Also, delete the option from the `// Test that we don't error on these.` block in test/Driver/clang_f_opts.c
2020-03-15 13:11:49 -07:00
Sjoerd Meijer 3d9a0445cc Recommit #2 "[Driver] Default to -fno-common for all targets"
After a first attempt to fix the test-suite failures, my first recommit
caused the same failures again. I had updated CMakeList.txt files of
tests that needed -fcommon, but it turns out that there are also
Makefiles which are used by some bots, so I've updated these Makefiles
now too.

See the original commit message for more details on this change:
0a9fc9233e
2020-03-09 19:57:03 +00:00
Sjoerd Meijer f35d112efd Revert "Recommit "[Driver] Default to -fno-common for all targets""
This reverts commit 2c36c23f34.

Still problems in the test-suite, which I really thought I had fixed...
2020-03-09 10:37:28 +00:00
Sjoerd Meijer 2c36c23f34 Recommit "[Driver] Default to -fno-common for all targets"
This includes fixes for:
- test-suite: some benchmarks need to be compiled with -fcommon, see D75557.
- compiler-rt: one test needed -fcommon, and another a change, see D75520.
2020-03-09 10:07:37 +00:00
Sjoerd Meijer 4e363563fa Revert "[Driver] Default to -fno-common for all targets"
This reverts commit 0a9fc9233e.

Going to look at the asan failures.

I find the failures in the test suite weird, because they look
like compile time test and I don't understand how that can be
failing, but will have a brief look at that too.
2020-03-03 10:00:36 +00:00
Sjoerd Meijer 0a9fc9233e [Driver] Default to -fno-common for all targets
This makes -fno-common the default for all targets because this has performance
and code-size benefits and is more language conforming for C code.
Additionally, GCC10 also defaults to -fno-common and so we get consistent
behaviour with GCC.

With this change, C code that uses tentative definitions as definitions of a
variable in multiple translation units will trigger multiple-definition linker
errors. Generally, this occurs when the use of the extern keyword is neglected
in the declaration of a variable in a header file. In some cases, no specific
translation unit provides a definition of the variable. The previous behavior
can be restored by specifying -fcommon.

As GCC has switched already, we benefit from applications already being ported
and existing documentation how to do this. For example:
- https://gcc.gnu.org/gcc-10/porting_to.html
- https://wiki.gentoo.org/wiki/Gcc_10_porting_notes/fno_common

Differential revision: https://reviews.llvm.org/D75056
2020-03-03 09:15:07 +00:00
Scott Linder 340feac672 [Driver] Escape the program path for -frecord-command-line
Similar to the rest of the command line that is recorded, the program
path must also have spaces and backslashes escaped. Without this
parsing the recorded command line becomes hard on platforms like
Windows where spaces and backslashes are common.

This was originally reverted in
577d9ce35532439203411c999deefc9c80e04c69; this version makes a test
agnostic to the presence of backslashes in paths on some platforms.

Patch By: Ravi Ramaseshan
Differential Revision: https://reviews.llvm.org/D74811
2020-02-21 19:16:59 -05:00
Scott Linder 577d9ce355 Revert "[Driver] Escape the program path for -frecord-command-line"
This reverts commit 6123074d0c.

Quoting/escaping rules seem host specific, so the test is failing on
some bots.
2020-02-20 17:36:56 -05:00
Scott Linder 6123074d0c [Driver] Escape the program path for -frecord-command-line
Similar to the rest of the command line that is recorded, the program
path must also have spaces and backslashes escaped. Without this
parsing the recorded command line becomes hard on platforms like
Windows where spaces and backslashes are common.

Patch By: Ravi Ramaseshan
Differential Revision: https://reviews.llvm.org/D74811
2020-02-20 16:31:17 -05:00
Jim Lin 492d4a992d [NFC] Update the testcase clang_f_opts.c for the removed options 2020-02-19 09:28:41 +08:00
Jim Lin ea789f819f Remove unused option that gcc ignored
Reviewers: efriedma, MaskRay

Reviewed By: efriedma, MaskRay

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72825
2020-02-19 08:36:07 +08:00
Fangrui Song aed488e3a4 [Driver] Move -fsemantic-interposition decision from cc1 to driver
And add test/Driver/fsemantic-interposition.c
2020-02-02 20:45:29 -08:00
serge-sans-paille fd09f12f32 Implement -fsemantic-interposition
First attempt at implementing -fsemantic-interposition.

Rely on GlobalValue::isInterposable that already captures most of the expected
behavior.

Rely on a ModuleFlag to state whether we should respect SemanticInterposition or
not. The default remains no.

So this should be a no-op if -fsemantic-interposition isn't used, and if it is,
isInterposable being already used in most optimisation, they should honor it
properly.

Note that it only impacts architecture compiled with -fPIC and no pie.

Differential Revision: https://reviews.llvm.org/D72829
2020-01-31 14:02:33 +01:00
Fangrui Song 5d1b3ba687 [Driver] Ignore -fno-semantic-interposition
Fedora wants to build projects with -fno-semantic-interposition (e.g.
https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup),
which is supported by GCC>=5.

Clang's current behavior is similar to -fno-semantic-interposition and
the end goal is to make it more so
(https://lists.llvm.org/pipermail/llvm-dev/2016-November/107625.html).
Ignore this option.

We should let users know -fsemantic-interposition is not currently
supported, so it should remain a hard error.

Reviewed By: serge-sans-paille

Differential Revision: https://reviews.llvm.org/D72724
2020-01-14 12:09:13 -08:00
Alexandre Ganea b4a99a061f [Clang][Driver] Re-use the calling process instead of creating a new process for the cc1 invocation
With this patch, the clang tool will now call the -cc1 invocation directly inside the same process. Previously, the -cc1 invocation was creating, and waiting for, a new process.
This patch therefore reduces the number of created processes during a build, thus it reduces build times on platforms where process creation can be costly (Windows) and/or impacted by a antivirus.
It also makes debugging a bit easier, as there's no need to attach to the secondary -cc1 process anymore, breakpoints will be hit inside the same process.

Crashes or signaling inside the -cc1 invocation will have the same side-effect as before, and will be reported through the same means.

This behavior can be controlled at compile-time through the CLANG_SPAWN_CC1 cmake flag, which defaults to OFF. Setting it to ON will revert to the previous behavior, where any -cc1 invocation will create/fork a secondary process.
At run-time, it is also possible to tweak the CLANG_SPAWN_CC1 environment variable. Setting it and will override the compile-time setting. A value of 0 calls -cc1 inside the calling process; a value of 1 will create a secondary process, as before.

Differential Revision: https://reviews.llvm.org/D69825
2020-01-13 10:40:18 -05:00
Nico Weber 44e0daf16e driver: Allow -fdebug-compilation-dir=foo in joined form.
All 130+ f_Group flags that take an argument allow it after a '=',
except for fdebug-complation-dir. Add a Joined<> alias so that
it behaves consistently with all the other f_Group flags.
(Keep the old Separate flag for backwards compat.)
2020-01-10 19:20:51 -05:00
Hans Wennborg dde7b6bcda Re-land "Add an -fno-temp-file flag for compilation"
This time making sure to initialize FrontendOptions::UseTemporary.

Patch by Zachary Henkel!

Differential revision: https://reviews.llvm.org/D70615
2019-12-19 13:34:52 +01:00
Mitch Phillips b19d87b16f Revert "Add an -fno-temp-file flag for compilation"
This reverts commit d129aa1d53.

This broke the MSan buildbots. More information available in the
original PR: https://reviews.llvm.org/D70615
2019-12-18 09:05:09 -08:00
Hans Wennborg d129aa1d53 Add an -fno-temp-file flag for compilation
Our build system does not handle randomly named files created during
the build well. We'd prefer to write compilation output directly
without creating a temporary file. Function parameters already
existed to control this behavior but were not exposed all the way out
to the command line.

Patch by Zachary Henkel!

Differential revision: https://reviews.llvm.org/D70615
2019-12-18 15:07:43 +01:00
Hans Wennborg 18b72d337e Also check /Fo when deciding on the .gcna / .gcda filename (PR44208)
Differential revision: https://reviews.llvm.org/D71012
2019-12-05 13:57:04 +01:00
Melanie Blower 7f9b513847 Reapply af57dbf12e "Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior="
Patch was reverted because https://bugs.llvm.org/show_bug.cgi?id=44048
        The original patch is modified to set the strictfp IR attribute
        explicitly in CodeGen instead of as a side effect of IRBuilder.
        In the 2nd attempt to reapply there was a windows lit test fail, the
        tests were fixed to use wildcard matching.

        Differential Revision: https://reviews.llvm.org/D62731
2019-12-05 03:48:04 -08:00
Melanie Blower 5412913631 Revert " Reapply af57dbf12e "Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior=""
This reverts commit cdbed2dd85.
Build break on Windows (lit fail)
2019-12-04 12:21:23 -08:00
Melanie Blower cdbed2dd85 Reapply af57dbf12e "Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior="
Patch was reverted because https://bugs.llvm.org/show_bug.cgi?id=44048
        The original patch is modified to set the strictfp IR attribute
        explicitly in CodeGen instead of as a side effect of IRBuilder

        Differential Revision: https://reviews.llvm.org/D62731
2019-12-04 11:32:33 -08:00
Eric Christopher 30e7ee3c4b Temporarily Revert "Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior="
and a follow-up NFC rearrangement as it's causing a crash on valid. Testcase is on the original review thread.

This reverts commits af57dbf12e and e6584b2b7b
2019-11-18 10:46:48 -08:00
Melanie Blower af57dbf12e Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior=
Add options to control floating point behavior: trapping and
    exception behavior, rounding, and control of optimizations that affect
    floating point calculations. More details in UsersManual.rst.

    Reviewers: rjmccall

    Differential Revision: https://reviews.llvm.org/D62731
2019-11-07 07:22:45 -08:00
Fangrui Song dc0396614f [Driver] Refactor interaction between -f(no-)?omit-frame-pointer and -m(no-)?omit-leaf-frame-pointer
Use a tri-state enum to represent shouldUseFramePointer() and
shouldUseLeafFramePointer().

This simplifies the logic and fixes PR9825:
  -fno-omit-frame-pointer doesn't imply -mno-omit-leaf-frame-pointer.

and PR24003:
  /Oy- /O2 should not omit leaf frame pointer: this matches MSVC x86-32.
  (/Oy- is a no-op on MSVC x86-64.)

and:
  when CC1 option -mdisable-fp-elim if absent, -momit-leaf-frame-pointer
  can also be omitted.

The new behavior matches GCC:
  -fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer
  -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer

The behavior makes lots of sense. We have 4 states:

- 00) leaf retained, non-leaf retained
- 01) leaf retained, non-leaf omitted  (this is invalid)
- 10) leaf omitted, non-leaf retained  (what -momit-leaf-frame-pointer was designed for)
- 11) leaf omitted, non-leaf omitted

"omit" options taking precedence over "no-omit" options is the only way
to make 3 valid states representable with -f(no-)?omit-frame-pointer and
-m(no-)?omit-leaf-pointer.

Reviewed By: ychen

Differential Revision: https://reviews.llvm.org/D64294

llvm-svn: 365860
2019-07-12 02:01:51 +00:00
Nico Weber 37b7533682 Promote -fdebug-compilation-dir from a cc1 flag to clang and clang-cl driver flags
The flag is useful when wanting to create .o files that are independent
from the absolute path to the build directory. -fdebug-prefix-map= can
be used to the same effect, but it requires putting the absolute path
to the build directory on the build command line, so it still requires
the build command line to be dependent on the absolute path of the build
directory. With this flag, "-fdebug-compilation-dir ." makes it so that
both debug info and the compile command itself are independent of the
absolute path of the build directory, which is good for build
determinism (in the sense that the build is independent of which
directory it happens in) and for caching compile results.
(The tradeoff is that the debugger needs explicit configuration to know
the build directory. See also http://dwarfstd.org/ShowIssue.php?issue=171130.2)

Differential Revision: https://reviews.llvm.org/D63387

llvm-svn: 363548
2019-06-17 12:10:40 +00:00
Manman Ren 394d4ccf69 Order File Instrumentation: add clang support for -forder-file-instrumentation
When -forder-file-instrumentation is on, we pass llvm flag to enable the order file instrumentation pass.

https://reviews.llvm.org/D58751

llvm-svn: 355333
2019-03-04 20:30:30 +00:00
JF Bastien 14daa20be1 Automatic variable initialization
Summary:
Add an option to initialize automatic variables with either a pattern or with
zeroes. The default is still that automatic variables are uninitialized. Also
add attributes to request uninitialized on a per-variable basis, mainly to disable
initialization of large stack arrays when deemed too expensive.

This isn't meant to change the semantics of C and C++. Rather, it's meant to be
a last-resort when programmers inadvertently have some undefined behavior in
their code. This patch aims to make undefined behavior hurt less, which
security-minded people will be very happy about. Notably, this means that
there's no inadvertent information leak when:

  - The compiler re-uses stack slots, and a value is used uninitialized.
  - The compiler re-uses a register, and a value is used uninitialized.
  - Stack structs / arrays / unions with padding are copied.

This patch only addresses stack and register information leaks. There's many
more infoleaks that we could address, and much more undefined behavior that
could be tamed. Let's keep this patch focused, and I'm happy to address related
issues elsewhere.

To keep the patch simple, only some `undef` is removed for now, see
`replaceUndef`. The padding-related infoleaks are therefore not all gone yet.
This will be addressed in a follow-up, mainly because addressing padding-related
leaks should be a stand-alone option which is implied by variable
initialization.

There are three options when it comes to automatic variable initialization:

  0. Uninitialized

    This is C and C++'s default. It's not changing. Depending on code
    generation, a programmer who runs into undefined behavior by using an
    uninialized automatic variable may observe any previous value (including
    program secrets), or any value which the compiler saw fit to materialize on
    the stack or in a register (this could be to synthesize an immediate, to
    refer to code or data locations, to generate cookies, etc).

  1. Pattern initialization

    This is the recommended initialization approach. Pattern initialization's
    goal is to initialize automatic variables with values which will likely
    transform logic bugs into crashes down the line, are easily recognizable in
    a crash dump, without being values which programmers can rely on for useful
    program semantics. At the same time, pattern initialization tries to
    generate code which will optimize well. You'll find the following details in
    `patternFor`:

    - Integers are initialized with repeated 0xAA bytes (infinite scream).
    - Vectors of integers are also initialized with infinite scream.
    - Pointers are initialized with infinite scream on 64-bit platforms because
      it's an unmappable pointer value on architectures I'm aware of. Pointers
      are initialize to 0x000000AA (small scream) on 32-bit platforms because
      32-bit platforms don't consistently offer unmappable pages. When they do
      it's usually the zero page. As people try this out, I expect that we'll
      want to allow different platforms to customize this, let's do so later.
    - Vectors of pointers are initialized the same way pointers are.
    - Floating point values and vectors are initialized with a negative quiet
      NaN with repeated 0xFF payload (e.g. 0xffffffff and 0xffffffffffffffff).
      NaNs are nice (here, anways) because they propagate on arithmetic, making
      it more likely that entire computations become NaN when a single
      uninitialized value sneaks in.
    - Arrays are initialized to their homogeneous elements' initialization
      value, repeated. Stack-based Variable-Length Arrays (VLAs) are
      runtime-initialized to the allocated size (no effort is made for negative
      size, but zero-sized VLAs are untouched even if technically undefined).
    - Structs are initialized to their heterogeneous element's initialization
      values. Zero-size structs are initialized as 0xAA since they're allocated
      a single byte.
    - Unions are initialized using the initialization for the largest member of
      the union.

    Expect the values used for pattern initialization to change over time, as we
    refine heuristics (both for performance and security). The goal is truly to
    avoid injecting semantics into undefined behavior, and we should be
    comfortable changing these values when there's a worthwhile point in doing
    so.

    Why so much infinite scream? Repeated byte patterns tend to be easy to
    synthesize on most architectures, and otherwise memset is usually very
    efficient. For values which aren't entirely repeated byte patterns, LLVM
    will often generate code which does memset + a few stores.

  2. Zero initialization

    Zero initialize all values. This has the unfortunate side-effect of
    providing semantics to otherwise undefined behavior, programs therefore
    might start to rely on this behavior, and that's sad. However, some
    programmers believe that pattern initialization is too expensive for them,
    and data might show that they're right. The only way to make these
    programmers wrong is to offer zero-initialization as an option, figure out
    where they are right, and optimize the compiler into submission. Until the
    compiler provides acceptable performance for all security-minded code, zero
    initialization is a useful (if blunt) tool.

I've been asked for a fourth initialization option: user-provided byte value.
This might be useful, and can easily be added later.

Why is an out-of band initialization mecanism desired? We could instead use
-Wuninitialized! Indeed we could, but then we're forcing the programmer to
provide semantics for something which doesn't actually have any (it's
uninitialized!). It's then unclear whether `int derp = 0;` lends meaning to `0`,
or whether it's just there to shut that warning up. It's also way easier to use
a compiler flag than it is to manually and intelligently initialize all values
in a program.

Why not just rely on static analysis? Because it cannot reason about all dynamic
code paths effectively, and it has false positives. It's a great tool, could get
even better, but it's simply incapable of catching all uses of uninitialized
values.

Why not just rely on memory sanitizer? Because it's not universally available,
has a 3x performance cost, and shouldn't be deployed in production. Again, it's
a great tool, it'll find the dynamic uses of uninitialized variables that your
test coverage hits, but it won't find the ones that you encounter in production.

What's the performance like? Not too bad! Previous publications [0] have cited
2.7 to 4.5% averages. We've commmitted a few patches over the last few months to
address specific regressions, both in code size and performance. In all cases,
the optimizations are generally useful, but variable initialization benefits
from them a lot more than regular code does. We've got a handful of other
optimizations in mind, but the code is in good enough shape and has found enough
latent issues that it's a good time to get the change reviewed, checked in, and
have others kick the tires. We'll continue reducing overheads as we try this out
on diverse codebases.

Is it a good idea? Security-minded folks think so, and apparently so does the
Microsoft Visual Studio team [1] who say "Between 2017 and mid 2018, this
feature would have killed 49 MSRC cases that involved uninitialized struct data
leaking across a trust boundary. It would have also mitigated a number of bugs
involving uninitialized struct data being used directly.". They seem to use pure
zero initialization, and claim to have taken the overheads down to within noise.
Don't just trust Microsoft though, here's another relevant person asking for
this [2]. It's been proposed for GCC [3] and LLVM [4] before.

What are the caveats? A few!

  - Variables declared in unreachable code, and used later, aren't initialized.
    This goto, Duff's device, other objectionable uses of switch. This should
    instead be a hard-error in any serious codebase.
  - Volatile stack variables are still weird. That's pre-existing, it's really
    the language's fault and this patch keeps it weird. We should deprecate
    volatile [5].
  - As noted above, padding isn't fully handled yet.

I don't think these caveats make the patch untenable because they can be
addressed separately.

Should this be on by default? Maybe, in some circumstances. It's a conversation
we can have when we've tried it out sufficiently, and we're confident that we've
eliminated enough of the overheads that most codebases would want to opt-in.
Let's keep our precious undefined behavior until that point in time.

How do I use it:

  1. On the command-line:

    -ftrivial-auto-var-init=uninitialized (the default)
    -ftrivial-auto-var-init=pattern
    -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang

  2. Using an attribute:

    int dont_initialize_me __attribute((uninitialized));

  [0]: https://users.elis.ugent.be/~jsartor/researchDocs/OOPSLA2011Zero-submit.pdf
  [1]: https://twitter.com/JosephBialek/status/1062774315098112001
  [2]: https://outflux.net/slides/2018/lss/danger.pdf
  [3]: https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00615.html
  [4]: 776a0955ef
  [5]: http://wg21.link/p1152

I've also posted an RFC to cfe-dev: http://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html

<rdar://problem/39131435>

Reviewers: pcc, kcc, rsmith

Subscribers: JDevlieghere, jkorous, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D54604

llvm-svn: 349442
2018-12-18 05:12:21 +00:00