diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-01-17 17:51:25 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-01-17 17:51:25 +0000 |
commit | bb9869d5a3e3a0f3673742ede7ea9bc325adbb4a (patch) | |
tree | 4ad7e64ad7b745b5bef09ce376f20f5235b2d803 /gcc | |
parent | d2edcd7083601bc08789787331399624b85b843b (diff) | |
download | gcc-bb9869d5a3e3a0f3673742ede7ea9bc325adbb4a.zip gcc-bb9869d5a3e3a0f3673742ede7ea9bc325adbb4a.tar.gz gcc-bb9869d5a3e3a0f3673742ede7ea9bc325adbb4a.tar.bz2 |
C++: Fix crash in warn_for_memset within templates (PR c++/83814)
gcc/c-family/ChangeLog:
PR c++/83814
* c-common.c (fold_for_warn): Move to c/c-fold.c and cp/expr.c.
gcc/c/ChangeLog:
PR c++/83814
* c-fold.c (fold_for_warn): Move from c-common.c, reducing to just
the C part.
gcc/cp/ChangeLog:
PR c++/83814
* expr.c (fold_for_warn): Move from c-common.c, reducing to just
the C++ part. If processing a template, call
fold_non_dependent_expr rather than fully folding.
gcc/testsuite/ChangeLog:
PR c++/83814
PR c++/83902
* g++.dg/wrappers/pr83814.C: New test case.
* g++.dg/wrappers/pr83902.C: New test case.
From-SVN: r256804
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 13 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 10 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/expr.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/wrappers/pr83814.C | 70 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/wrappers/pr83902.C | 9 |
9 files changed, 129 insertions, 13 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1e490af..d5012e2 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2018-01-17 David Malcolm <dmalcolm@redhat.com> + + PR c++/83814 + * c-common.c (fold_for_warn): Move to c/c-fold.c and cp/expr.c. + 2018-01-10 Eric Botcazou <ebotcazou@adacore.com> * c-ada-spec.c (dump_number): Add FLOAT_P parameter. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 097d192..858ed68 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -868,19 +868,6 @@ c_get_substring_location (const substring_loc &substr_loc, } -/* Fold X for consideration by one of the warning functions when checking - whether an expression has a constant value. */ - -tree -fold_for_warn (tree x) -{ - if (c_dialect_cxx ()) - return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL); - else - /* The C front-end has already folded X appropriately. */ - return x; -} - /* Return true iff T is a boolean promoted to int. */ bool diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 95404fb..52ed9f0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-01-17 David Malcolm <dmalcolm@redhat.com> + + PR c++/83814 + * c-fold.c (fold_for_warn): Move from c-common.c, reducing to just + the C part. + 2018-01-13 Jakub Jelinek <jakub@redhat.com> PR c/83801 diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 12460bc..480e34c 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -676,3 +676,13 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, } return ret; } + +/* Fold X for consideration by one of the warning functions when checking + whether an expression has a constant value. */ + +tree +fold_for_warn (tree x) +{ + /* The C front-end has already folded X appropriately. */ + return x; +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bdcac47..49cf0c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-01-17 David Malcolm <dmalcolm@redhat.com> + + PR c++/83814 + * expr.c (fold_for_warn): Move from c-common.c, reducing to just + the C++ part. If processing a template, call + fold_non_dependent_expr rather than fully folding. + 2018-01-17 Jason Merrill <jason@redhat.com> PR c++/81067 - redundant NULL warning. diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index da09ab8..49a17a6 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -315,3 +315,18 @@ mark_exp_read (tree exp) } } +/* Fold X for consideration by one of the warning functions when checking + whether an expression has a constant value. */ + +tree +fold_for_warn (tree x) +{ + /* C++ implementation. */ + + /* It's not generally safe to fully fold inside of a template, so + call fold_non_dependent_expr instead. */ + if (processing_template_decl) + return fold_non_dependent_expr (x); + + return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL); +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dd25a37..d6c744e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2018-01-17 David Malcolm <dmalcolm@redhat.com> + PR c++/83814 + PR c++/83902 + * g++.dg/wrappers/pr83814.C: New test case. + * g++.dg/wrappers/pr83902.C: New test case. + +2018-01-17 David Malcolm <dmalcolm@redhat.com> + PR lto/83121 * g++.dg/lto/pr83121_0.C: New test case. * g++.dg/lto/pr83121_1.C: New test case. diff --git a/gcc/testsuite/g++.dg/wrappers/pr83814.C b/gcc/testsuite/g++.dg/wrappers/pr83814.C new file mode 100644 index 0000000..b9f8faa --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/pr83814.C @@ -0,0 +1,70 @@ +/* Verify that our memset warnings don't crash when folding + arguments within a template (PR c++/83814). */ + +// { dg-options "-Wno-int-to-pointer-cast -Wmemset-transposed-args -Wmemset-elt-size" } + +template <class> +void test_1() +{ + __builtin_memset (int() - char(), 0, 0); +} + +template <class> +void test_2() +{ + __builtin_memset (0, 0, int() - char()); +} + +template <class> +void test_3 (unsigned a, int c) +{ + __builtin_memset((char *)c + a, 0, a); +} + +template <class> +void test_4 (unsigned a, int c) +{ + __builtin_memset(0, 0, (char *)c + a); +} + +/* Verify that we warn for -Wmemset-transposed-args inside + a template. */ + +char buf[1024]; + +template <class> +void test_5 () +{ + __builtin_memset (buf, sizeof buf, 0); // { dg-warning "transposed parameters" } +} + +/* Adapted from c-c++-common/memset-array.c; verify that + -Wmemset-elt-size works within a template. */ + +enum a { + a_1, + a_2, + a_n +}; +int t1[20]; +int t2[a_n]; + +struct s +{ + int t[20]; +}; + +template<class> +void foo (struct s *s) +{ + __builtin_memset (t1, 0, 20); // { dg-warning "element size" } + + // This case requires reading through an enum value: + __builtin_memset (t2, 0, a_n); // { dg-warning "element size" } + + __builtin_memset (s->t, 0, 20); // { dg-warning "element size" } + + // These cases require folding of arg2 within a template: + __builtin_memset (t2, 0, a_n + 0); // { dg-warning "element size" } + __builtin_memset (t2, 0, a_n * 1); // { dg-warning "element size" } +} diff --git a/gcc/testsuite/g++.dg/wrappers/pr83902.C b/gcc/testsuite/g++.dg/wrappers/pr83902.C new file mode 100644 index 0000000..3d334e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/pr83902.C @@ -0,0 +1,9 @@ +extern "C" void *memset (void *, int, __SIZE_TYPE__); +void *p; + +template <int T> +struct B +{ + void foo () { memset (p, 0, 4 * T * sizeof(float)); } +}; + |