diff options
author | Marek Polacek <polacek@redhat.com> | 2015-07-31 11:12:57 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2015-07-31 11:12:57 +0000 |
commit | ec043522ffe0847f1917b5065d3b72c29d601bef (patch) | |
tree | 010ad1c7522a6e03f5fae865df755dbe7f564f09 /gcc | |
parent | b5d3d7871c2e395fb7162712aebb81c90da3689b (diff) | |
download | gcc-ec043522ffe0847f1917b5065d3b72c29d601bef.zip gcc-ec043522ffe0847f1917b5065d3b72c29d601bef.tar.gz gcc-ec043522ffe0847f1917b5065d3b72c29d601bef.tar.bz2 |
re PR sanitizer/66977 (-fsanitize=shift may introduce uninitialized variables)
PR sanitizer/66977
* typeck.c (get_member_function_from_ptrfunc): Don't sanitize
RSHIFT_EXPR.
* g++.dg/ubsan/pr66977.C: New test.
From-SVN: r226440
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr66977.C | 27 |
4 files changed, 45 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c1a7cb6..8d286a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-07-31 Marek Polacek <polacek@redhat.com> + + PR sanitizer/66977 + * typeck.c (get_member_function_from_ptrfunc): Don't sanitize + RSHIFT_EXPR. + 2015-07-30 Paolo Carlini <paolo.carlini@oracle.com> * class.c (check_for_override): Use DECL_SOURCE_LOCATION and "%qD" diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 2ed43be..a7a8844 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3288,6 +3288,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, idx = build1 (NOP_EXPR, vtable_index_type, e3); switch (TARGET_PTRMEMFUNC_VBIT_LOCATION) { + int flag_sanitize_save; case ptrmemfunc_vbit_in_pfn: e1 = cp_build_binary_op (input_location, BIT_AND_EXPR, idx, integer_one_node, @@ -3303,9 +3304,15 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, e1 = cp_build_binary_op (input_location, BIT_AND_EXPR, delta, integer_one_node, complain); + /* Don't instrument the RSHIFT_EXPR we're about to create because + we're going to use DELTA number of times, and that wouldn't play + well with SAVE_EXPRs therein. */ + flag_sanitize_save = flag_sanitize; + flag_sanitize = 0; delta = cp_build_binary_op (input_location, RSHIFT_EXPR, delta, integer_one_node, complain); + flag_sanitize = flag_sanitize_save; if (delta == error_mark_node) return error_mark_node; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08ea0c8..6513cf0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-31 Marek Polacek <polacek@redhat.com> + + PR sanitizer/66977 + * g++.dg/ubsan/pr66977.C: New test. + 2015-07-30 Marek Polacek <polacek@redhat.com> * c-c++-common/Wtautological-compare-3.c: New test. diff --git a/gcc/testsuite/g++.dg/ubsan/pr66977.C b/gcc/testsuite/g++.dg/ubsan/pr66977.C new file mode 100644 index 0000000..3ab8d90 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr66977.C @@ -0,0 +1,27 @@ +// PR sanitizer/66977 +// { dg-do compile } +// { dg-options "-fsanitize=shift -Wmaybe-uninitialized -O" } + +class Foo { + +private: + + int a_; + +public: + + Foo (int a) : a_(a) {}; + + inline int get_a () { return a_; }; +}; + +int bar (int (Foo::*get)()) { + Foo *A = new Foo(1); + int result = (A->*get)(); + delete (A); + return result; +} + +int main () { + return bar (&Foo::get_a); +} |