re PR sanitizer/66977 (-fsanitize=shift may introduce uninitialized variables)
authorMarek Polacek <polacek@redhat.com>
Fri, 31 Jul 2015 11:12:57 +0000 (11:12 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 31 Jul 2015 11:12:57 +0000 (11:12 +0000)
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

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr66977.C [new file with mode: 0644]

index c1a7cb6f3526f78fc5ebeaeffb7aa6e89ceba19a..8d286a62d9e394a1be2f331cf20d4f709a471683 100644 (file)
@@ -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"
index 2ed43beeb0d1edc1a5885559838f545d2218779a..a7a884486fe31b373e8049c1c59a6961bafca565 100644 (file)
@@ -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;
index 08ea0c8dccc5f2ec09f101e750df57073eba5655..6513cf01b2c00be1e561cc9d41af1c0d5d322468 100644 (file)
@@ -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 (file)
index 0000000..3ab8d90
--- /dev/null
@@ -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);
+}