From bb9869d5a3e3a0f3673742ede7ea9bc325adbb4a Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 17 Jan 2018 17:51:25 +0000 Subject: [PATCH] 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 --- gcc/c-family/ChangeLog | 5 ++ gcc/c-family/c-common.c | 13 ----- gcc/c/ChangeLog | 6 +++ gcc/c/c-fold.c | 10 ++++ gcc/cp/ChangeLog | 7 +++ gcc/cp/expr.c | 15 ++++++ gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/g++.dg/wrappers/pr83814.C | 70 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/wrappers/pr83902.C | 9 ++++ 9 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/wrappers/pr83814.C create mode 100644 gcc/testsuite/g++.dg/wrappers/pr83902.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1e490afe331..d5012e251b4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2018-01-17 David Malcolm + + PR c++/83814 + * c-common.c (fold_for_warn): Move to c/c-fold.c and cp/expr.c. + 2018-01-10 Eric Botcazou * 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 097d192c869..858ed68f2d1 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 95404fb5f54..52ed9f05e4c 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-01-17 David Malcolm + + 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 PR c/83801 diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 12460bc93d5..480e34ce4f4 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 bdcac476385..49cf0c05a5c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-01-17 David Malcolm + + 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 PR c++/81067 - redundant NULL warning. diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index da09ab844cf..49a17a62424 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 dd25a3746b8..d6c744e60de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-01-17 David Malcolm + + 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 PR lto/83121 diff --git a/gcc/testsuite/g++.dg/wrappers/pr83814.C b/gcc/testsuite/g++.dg/wrappers/pr83814.C new file mode 100644 index 00000000000..b9f8faad92f --- /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 +void test_1() +{ + __builtin_memset (int() - char(), 0, 0); +} + +template +void test_2() +{ + __builtin_memset (0, 0, int() - char()); +} + +template +void test_3 (unsigned a, int c) +{ + __builtin_memset((char *)c + a, 0, a); +} + +template +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 +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 +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 00000000000..3d334e768d6 --- /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 +struct B +{ + void foo () { memset (p, 0, 4 * T * sizeof(float)); } +}; + -- 2.30.2