aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2015-07-31 11:12:57 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2015-07-31 11:12:57 +0000
commitec043522ffe0847f1917b5065d3b72c29d601bef (patch)
tree010ad1c7522a6e03f5fae865df755dbe7f564f09 /gcc
parentb5d3d7871c2e395fb7162712aebb81c90da3689b (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr66977.C27
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);
+}