aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/c-c++-common/auto-init-padding-2.c
diff options
context:
space:
mode:
authorqing zhao <qing.zhao@oracle.com>2021-09-09 15:44:49 -0700
committerqing zhao <qing.zhao@oracle.com>2021-09-09 15:44:49 -0700
commita25e0b5e6ac8a77a71c229e0a7b744603365b0e9 (patch)
treee46dad7fa274dc376be2ccf4735b5333c5d34315 /gcc/testsuite/c-c++-common/auto-init-padding-2.c
parent5fe0865ab788bdc387b284a3ad57e5a95a767b18 (diff)
downloadgcc-a25e0b5e6ac8a77a71c229e0a7b744603365b0e9.zip
gcc-a25e0b5e6ac8a77a71c229e0a7b744603365b0e9.tar.gz
gcc-a25e0b5e6ac8a77a71c229e0a7b744603365b0e9.tar.bz2
Add -ftrivial-auto-var-init option and uninitialized variable attribute.
Initialize automatic variables with either a pattern or with zeroes to increase the security and predictability of a program by preventing uninitialized memory disclosure and use. GCC still considers an automatic variable that doesn't have an explicit initializer as uninitialized, -Wuninitialized will still report warning messages on such automatic variables. With this option, GCC will also initialize any padding of automatic variables that have structure or union types to zeroes. You can control this behavior for a specific variable by using the variable attribute "uninitialized" to control runtime overhead. gcc/ChangeLog: 2021-09-09 qing zhao <qing.zhao@oracle.com> * builtins.c (expand_builtin_memset): Make external visible. * builtins.h (expand_builtin_memset): Declare extern. * common.opt (ftrivial-auto-var-init=): New option. * doc/extend.texi: Document the uninitialized attribute. * doc/invoke.texi: Document -ftrivial-auto-var-init. * flag-types.h (enum auto_init_type): New enumerated type auto_init_type. * gimple-fold.c (clear_padding_type): Add one new parameter. (clear_padding_union): Likewise. (clear_padding_emit_loop): Likewise. (clear_type_padding_in_mask): Likewise. (gimple_fold_builtin_clear_padding): Handle this new parameter. * gimplify.c (gimple_add_init_for_auto_var): New function. (gimple_add_padding_init_for_auto_var): New function. (is_var_need_auto_init): New function. (gimplify_decl_expr): Add initialization to automatic variables per users' requests. (gimplify_call_expr): Add one new parameter for call to __builtin_clear_padding. (gimplify_init_constructor): Add padding initialization in the end. * internal-fn.c (INIT_PATTERN_VALUE): New macro. (expand_DEFERRED_INIT): New function. * internal-fn.def (DEFERRED_INIT): New internal function. * tree-cfg.c (verify_gimple_call): Verify calls to .DEFERRED_INIT. * tree-sra.c (generate_subtree_deferred_init): New function. (scan_function): Avoid setting cannot_scalarize_away_bitmap for calls to .DEFERRED_INIT. (sra_modify_deferred_init): New function. (sra_modify_function_body): Handle calls to DEFERRED_INIT specially. * tree-ssa-structalias.c (find_func_aliases_for_call): Likewise. * tree-ssa-uninit.c (warn_uninit): Handle calls to DEFERRED_INIT specially. (check_defs): Likewise. (warn_uninitialized_vars): Likewise. * tree-ssa.c (ssa_undefined_value_p): Likewise. * tree.c (build_common_builtin_nodes): Build tree node for BUILT_IN_CLEAR_PADDING when needed. gcc/c-family/ChangeLog: 2021-09-09 qing zhao <qing.zhao@oracle.com> * c-attribs.c (handle_uninitialized_attribute): New function. (c_common_attribute_table): Add "uninitialized" attribute. gcc/testsuite/ChangeLog: 2021-09-09 qing zhao <qing.zhao@oracle.com> * c-c++-common/auto-init-1.c: New test. * c-c++-common/auto-init-10.c: New test. * c-c++-common/auto-init-11.c: New test. * c-c++-common/auto-init-12.c: New test. * c-c++-common/auto-init-13.c: New test. * c-c++-common/auto-init-14.c: New test. * c-c++-common/auto-init-15.c: New test. * c-c++-common/auto-init-16.c: New test. * c-c++-common/auto-init-2.c: New test. * c-c++-common/auto-init-3.c: New test. * c-c++-common/auto-init-4.c: New test. * c-c++-common/auto-init-5.c: New test. * c-c++-common/auto-init-6.c: New test. * c-c++-common/auto-init-7.c: New test. * c-c++-common/auto-init-8.c: New test. * c-c++-common/auto-init-9.c: New test. * c-c++-common/auto-init-esra.c: New test. * c-c++-common/auto-init-padding-1.c: New test. * c-c++-common/auto-init-padding-2.c: New test. * c-c++-common/auto-init-padding-3.c: New test. * g++.dg/auto-init-uninit-pred-1_a.C: New test. * g++.dg/auto-init-uninit-pred-2_a.C: New test. * g++.dg/auto-init-uninit-pred-3_a.C: New test. * g++.dg/auto-init-uninit-pred-4.C: New test. * gcc.dg/auto-init-sra-1.c: New test. * gcc.dg/auto-init-sra-2.c: New test. * gcc.dg/auto-init-uninit-1.c: New test. * gcc.dg/auto-init-uninit-12.c: New test. * gcc.dg/auto-init-uninit-13.c: New test. * gcc.dg/auto-init-uninit-14.c: New test. * gcc.dg/auto-init-uninit-15.c: New test. * gcc.dg/auto-init-uninit-16.c: New test. * gcc.dg/auto-init-uninit-17.c: New test. * gcc.dg/auto-init-uninit-18.c: New test. * gcc.dg/auto-init-uninit-19.c: New test. * gcc.dg/auto-init-uninit-2.c: New test. * gcc.dg/auto-init-uninit-20.c: New test. * gcc.dg/auto-init-uninit-21.c: New test. * gcc.dg/auto-init-uninit-22.c: New test. * gcc.dg/auto-init-uninit-23.c: New test. * gcc.dg/auto-init-uninit-24.c: New test. * gcc.dg/auto-init-uninit-25.c: New test. * gcc.dg/auto-init-uninit-26.c: New test. * gcc.dg/auto-init-uninit-3.c: New test. * gcc.dg/auto-init-uninit-34.c: New test. * gcc.dg/auto-init-uninit-36.c: New test. * gcc.dg/auto-init-uninit-37.c: New test. * gcc.dg/auto-init-uninit-4.c: New test. * gcc.dg/auto-init-uninit-5.c: New test. * gcc.dg/auto-init-uninit-6.c: New test. * gcc.dg/auto-init-uninit-8.c: New test. * gcc.dg/auto-init-uninit-9.c: New test. * gcc.dg/auto-init-uninit-A.c: New test. * gcc.dg/auto-init-uninit-B.c: New test. * gcc.dg/auto-init-uninit-C.c: New test. * gcc.dg/auto-init-uninit-H.c: New test. * gcc.dg/auto-init-uninit-I.c: New test. * gcc.target/aarch64/auto-init-1.c: New test. * gcc.target/aarch64/auto-init-2.c: New test. * gcc.target/aarch64/auto-init-3.c: New test. * gcc.target/aarch64/auto-init-4.c: New test. * gcc.target/aarch64/auto-init-5.c: New test. * gcc.target/aarch64/auto-init-6.c: New test. * gcc.target/aarch64/auto-init-7.c: New test. * gcc.target/aarch64/auto-init-8.c: New test. * gcc.target/aarch64/auto-init-padding-1.c: New test. * gcc.target/aarch64/auto-init-padding-10.c: New test. * gcc.target/aarch64/auto-init-padding-11.c: New test. * gcc.target/aarch64/auto-init-padding-12.c: New test. * gcc.target/aarch64/auto-init-padding-2.c: New test. * gcc.target/aarch64/auto-init-padding-3.c: New test. * gcc.target/aarch64/auto-init-padding-4.c: New test. * gcc.target/aarch64/auto-init-padding-5.c: New test. * gcc.target/aarch64/auto-init-padding-6.c: New test. * gcc.target/aarch64/auto-init-padding-7.c: New test. * gcc.target/aarch64/auto-init-padding-8.c: New test. * gcc.target/aarch64/auto-init-padding-9.c: New test. * gcc.target/i386/auto-init-1.c: New test. * gcc.target/i386/auto-init-2.c: New test. * gcc.target/i386/auto-init-21.c: New test. * gcc.target/i386/auto-init-22.c: New test. * gcc.target/i386/auto-init-23.c: New test. * gcc.target/i386/auto-init-24.c: New test. * gcc.target/i386/auto-init-3.c: New test. * gcc.target/i386/auto-init-4.c: New test. * gcc.target/i386/auto-init-5.c: New test. * gcc.target/i386/auto-init-6.c: New test. * gcc.target/i386/auto-init-7.c: New test. * gcc.target/i386/auto-init-8.c: New test. * gcc.target/i386/auto-init-padding-1.c: New test. * gcc.target/i386/auto-init-padding-10.c: New test. * gcc.target/i386/auto-init-padding-11.c: New test. * gcc.target/i386/auto-init-padding-12.c: New test. * gcc.target/i386/auto-init-padding-2.c: New test. * gcc.target/i386/auto-init-padding-3.c: New test. * gcc.target/i386/auto-init-padding-4.c: New test. * gcc.target/i386/auto-init-padding-5.c: New test. * gcc.target/i386/auto-init-padding-6.c: New test. * gcc.target/i386/auto-init-padding-7.c: New test. * gcc.target/i386/auto-init-padding-8.c: New test. * gcc.target/i386/auto-init-padding-9.c: New test.
Diffstat (limited to 'gcc/testsuite/c-c++-common/auto-init-padding-2.c')
-rw-r--r--gcc/testsuite/c-c++-common/auto-init-padding-2.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/auto-init-padding-2.c b/gcc/testsuite/c-c++-common/auto-init-padding-2.c
new file mode 100644
index 0000000..e2b50dc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-padding-2.c
@@ -0,0 +1,114 @@
+/* To test that the compiler can fill all the paddings to zeroes for the
+ structures when the auto variable is partially initialized, fully
+ initialized, or not initialized for -ftrivial-auto-var-init=zero. */
+/* { dg-do run} */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+/* Structure with no padding. */
+struct test_packed {
+ unsigned long one;
+ unsigned long two;
+ unsigned long three;
+ unsigned long four;
+} p1;
+
+/* Simple structure with padding likely to be covered by compiler. */
+struct test_small_hole {
+ unsigned long one;
+ char two;
+ /* 3 byte padding hole here. */
+ int three;
+ unsigned long four;
+} sh1;
+
+/* Try to trigger unhandled padding in a structure. */
+struct test_aligned {
+ unsigned int internal1;
+ unsigned long long internal2;
+} __attribute__((__aligned__(64)));
+
+struct test_aligned a1;
+
+struct test_big_hole {
+ unsigned char one;
+ unsigned char two;
+ unsigned char three;
+ /* 61 byte padding hole here. */
+ struct test_aligned four;
+} __attribute__((__aligned__(64)));
+
+struct test_big_hole bh1;
+
+struct test_trailing_hole {
+ char *one;
+ char *two;
+ char *three;
+ char four;
+ /* "sizeof(unsigned long) - 1" byte padding hole here. */
+} th1;
+
+__attribute__((noipa)) void
+foo (struct test_packed *p, struct test_small_hole *sh, struct test_aligned *a,
+ struct test_big_hole *bh, struct test_trailing_hole *th)
+{
+ p->one = 1; p->two = 2; p->three = 3; p->four = 4;
+ sh->one = 11; sh->two = 12; sh->three = 13; sh->four = 14;
+ a->internal1 = 21; a->internal2 = 22;
+ bh->one = 31; bh->two = 32; bh->three = 33;
+ bh->four.internal1 = 34; bh->four.internal2 = 35;
+ th->one = 0; th->two = 0; th->three = 0; th->four = 44;
+}
+
+int main ()
+{
+ struct test_packed p2;
+ struct test_small_hole sh2;
+ struct test_aligned a2;
+ struct test_big_hole bh2;
+ struct test_trailing_hole th2;
+
+ struct test_packed p3 = {.one = 1};
+ struct test_small_hole sh3 = {.two = 12};
+ struct test_aligned a3 = {.internal1 = 21};
+ struct test_big_hole bh3 = {.one = 31};
+ struct test_trailing_hole th3 = {.three = 0};
+
+ struct test_packed p4 = {.one = 1, .two = 2, .three = 3, .four = 4};
+ struct test_small_hole sh4 = {.one = 11, .two = 12, .three = 13, .four = 14};
+ struct test_aligned a4 = {.internal1 = 21, .internal2 = 22};
+ struct test_big_hole bh4 = {.one = 31, .two = 32, .three = 33};
+ struct test_trailing_hole th4 = {.one = 0, .two = 0, .three = 0, .four = 44};
+
+ foo (&p1, &sh1, &a1, &bh1, &th1);
+ foo (&p2, &sh2, &a2, &bh2, &th2);
+ foo (&p3, &sh3, &a3, &bh3, &th3);
+ bh4.four.internal1 = 34; bh4.four.internal2 = 35;
+
+ __builtin_clear_padding (&p1);
+ __builtin_clear_padding (&sh1);
+ __builtin_clear_padding (&a1);
+ __builtin_clear_padding (&bh1);
+ __builtin_clear_padding (&th1);
+
+ if (__builtin_memcmp (&p1, &p2, sizeof (p1))
+ || __builtin_memcmp (&sh1, &sh2, sizeof (sh1))
+ || __builtin_memcmp (&a1, &a2, sizeof (a1))
+ || __builtin_memcmp (&bh1, &bh2, sizeof (bh1))
+ || __builtin_memcmp (&th1, &th2, sizeof (th1)))
+ __builtin_abort ();
+ if (__builtin_memcmp (&p1, &p3, sizeof (p1))
+ || __builtin_memcmp (&sh1, &sh3, sizeof (sh1))
+ || __builtin_memcmp (&a1, &a3, sizeof (a1))
+ || __builtin_memcmp (&bh1, &bh3, sizeof (bh1))
+ || __builtin_memcmp (&th1, &th3, sizeof (th1)))
+ __builtin_abort ();
+ if (__builtin_memcmp (&p1, &p4, sizeof (p1))
+ || __builtin_memcmp (&sh1, &sh4, sizeof (sh1))
+ || __builtin_memcmp (&a1, &a4, sizeof (a1))
+ || __builtin_memcmp (&bh1, &bh4, sizeof (bh1))
+ || __builtin_memcmp (&th1, &th4, sizeof (th1)))
+ __builtin_abort ();
+
+
+ return 0;
+}