From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25604 invoked by alias); 9 Dec 2015 17:08:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 24814 invoked by uid 89); 9 Dec 2015 17:08:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,KAM_ASCII_DIVIDERS,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 09 Dec 2015 17:08:49 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id AB72FC0B7A36; Wed, 9 Dec 2015 17:08:47 +0000 (UTC) Received: from 640k.localdomain.com ([10.3.112.10]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tB9H8hBD003785; Wed, 9 Dec 2015 12:08:44 -0500 From: Paolo Bonzini To: gcc-patches@gcc.gnu.org, joseph@codesourcery.com, jakub@redhat.com, mpolacek@redhat.com, law@redhat.com Subject: [PATCH v2] Do not sanitize left shifts for -fwrapv (PR68418) Date: Wed, 09 Dec 2015 17:08:00 -0000 Message-Id: <1449680920-64273-1-git-send-email-pbonzini@redhat.com> X-SW-Source: 2015-12/txt/msg01034.txt.bz2 Left shifts into the sign bit is a kind of overflow, and the standard chooses to treat left shifts of negative values the same way. However, the -fwrapv option modifies the language to one where integers are defined as two's complement---which also defines entirely the behavior of shifts. Disable sanitization of left shifts when -fwrapv is in effect, using the same logic as instrument_si_overflow. The same change was proposed for LLVM at https://llvm.org/bugs/show_bug.cgi?id=25552. Bootstrapped/regtested x86_64-pc-linux-gnu. Ok for trunk, and for GCC 5 branch after 5.3 is released? Thanks, Paolo gcc: PR sanitizer/68418 * c-family/c-ubsan.c (ubsan_instrument_shift): Disable sanitization of left shifts for wrapping signed types as well. gcc/testsuite: PR sanitizer/68418 * gcc.dg/ubsan/c99-wrapv-shift-1.c, gcc.dg/ubsan/c99-wrapv-shift-2.c: New testcases. Index: c-family/c-ubsan.c =================================================================== --- c-family/c-ubsan.c (revision 231289) +++ c-family/c-ubsan.c (working copy) @@ -124,12 +124,17 @@ ubsan_instrument_shift (location_t loc, enum tree_ t = fold_convert_loc (loc, op1_utype, op1); t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1); + /* If this is not a signed operation, don't perform overflow checks. + Also punt on bit-fields. */ + if (!INTEGRAL_TYPE_P (type0) + || TYPE_OVERFLOW_WRAPS (type0) + || GET_MODE_BITSIZE (TYPE_MODE (type0)) != TYPE_PRECISION (type0)) + ; + /* For signed x << y, in C99/C11, the following: (unsigned) x >> (uprecm1 - y) if non-zero, is undefined. */ - if (code == LSHIFT_EXPR - && !TYPE_UNSIGNED (type0) - && flag_isoc99) + else if (code == LSHIFT_EXPR && flag_isoc99 && cxx_dialect < cxx11) { tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1, fold_convert (op1_utype, unshare_expr (op1))); @@ -142,9 +147,7 @@ ubsan_instrument_shift (location_t loc, enum tree_ /* For signed x << y, in C++11 and later, the following: x < 0 || ((unsigned) x >> (uprecm1 - y)) if > 1, is undefined. */ - if (code == LSHIFT_EXPR - && !TYPE_UNSIGNED (type0) - && (cxx_dialect >= cxx11)) + else if (code == LSHIFT_EXPR && cxx_dialect >= cxx11) { tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1, fold_convert (op1_utype, unshare_expr (op1))); Index: testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c =================================================================== --- testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c (revision 0) +++ testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c (working copy) @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -fwrapv -w -std=c99" } */ + +int +main (void) +{ + int a = -42; + a << 1; +} Index: testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c =================================================================== --- testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c (revision 0) +++ testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c (working copy) @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -fwrapv -w -std=c99" } */ + +int +main (void) +{ + int a = 1; + a <<= 31; +}