From patchwork Mon Jul 15 17:48:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 259152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 4E8182C0095 for ; Tue, 16 Jul 2013 03:49:25 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=xTWeZPIXqGzDKaA5j7Egw+Zd8aqSQYCKWD1ZH7wSn0cYBr8upH 6NGkIK0f23urPPPjOfs/4Waow89bN5cgjGJ3rJMbPs5AefKN+dwEPql1/60omh2L tu0iRy5uCwwKTgrUTyJE2TVjG59v2+XtYFlhyI0Fz393HuHUZc7m9JF6M= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=5bUgvEZyaEmq/fz+WPCgrgvA+Ic=; b=shsz5UXjCqY+bvUGOE6x ILZLtVk+GeyWaSQQ6tzCwJKm+lcI6OU/eVsVSw5LhRxlu7naghcj1uoOhIKe54k5 t1XgmoAX+0DdM3OI732ua2oROh1Vfy2SpIRNyMHIIRWJPJ4Nve3WIYivlLKIhYeD e0zfhCrkXc7QB7EKkxE8re8= Received: (qmail 8965 invoked by alias); 15 Jul 2013 17:49:17 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 8956 invoked by uid 89); 15 Jul 2013 17:49:16 -0000 X-Spam-SWARE-Status: No, score=-4.4 required=5.0 tests=AWL, BAYES_50, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RDNS_NONE, SPF_HELO_PASS, SPF_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 15 Jul 2013 17:49:15 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6FHn8SV015699 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 15 Jul 2013 13:49:08 -0400 Received: from redhat.com (ovpn-116-36.ams2.redhat.com [10.36.116.36]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r6FHn0qq001902 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Mon, 15 Jul 2013 13:49:05 -0400 Date: Mon, 15 Jul 2013 19:48:59 +0200 From: Marek Polacek To: GCC Patches Cc: Jakub Jelinek Subject: [ubsan] Add testsuite Message-ID: <20130715174859.GL3697@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Ubsan testsuite is something we've been missing for some time now, so this patch adds it. Fortunately the dejagnu part was quite simple, since ubsan doesn't need similar tweaks as asan does. But I had to tweak gcc.c to include -lubsan. The tests are testing pretty basic stuff, however, in LLVM testsuite they don't check much more. Maybe we should test also stuff like ++a << (v * x) etc.? Tested with make check RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} ubsan.exp' Any comments before I put this on ubsan branch? 2013-07-15 Marek Polacek * gcc.c (ADD_STATIC_LIBUBSAN_LIBS): Define. (LIBUBSAN_SPEC): Likewise. (LIBUBSAN_EARLY_SPEC): Likewise. (SANITIZER_SPEC): Handle libubsan. (SANITIZER_EARLY_SPEC): Likewise. testsuite/ * lib/ubsan-dg.exp: New file. * g++.dg/ubsan/ubsan.exp: New file. * gcc.dg/ubsan/ubsan.exp: New file. * g++.dg/ubsan/cxx11-shift-1.C: New test. * g++.dg/ubsan/cxx11-shift-2.C: New test. * c-c++-common/ubsan/div-by-zero-3.c: New test. * c-c++-common/ubsan/div-by-zero-1.c: New test. * c-c++-common/ubsan/div-by-zero-4.c: New test. * c-c++-common/ubsan/shift-3.c: New test. * c-c++-common/ubsan/unreachable-1.c: New test. * c-c++-common/ubsan/shift-1.c: New test. * c-c++-common/ubsan/shift-2.c: New test. * c-c++-common/ubsan/div-by-zero-2.c: New test. * gcc.dg/ubsan/c99-shift-2.c: New test. * gcc.dg/ubsan/c99-shift-1.c: New test. Marek --- gcc/gcc.c.mp 2013-07-15 04:30:13.038677937 +0200 +++ gcc/gcc.c 2013-07-15 04:42:32.257592503 +0200 @@ -591,6 +591,28 @@ proper position among the other output f #define LIBTSAN_EARLY_SPEC "" #endif +#ifndef LIBUBSAN_SPEC +#ifdef STATIC_LIBUBSAN_LIBS +#define ADD_STATIC_LIBUBSAN_LIBS \ + " %{static-libubsan:" STATIC_LIBUBSAN_LIBS "}" +#else +#define ADD_STATIC_LIBUBSAN_LIBS +#endif +#ifdef LIBUBSAN_EARLY_SPEC +#define LIBUBSAN_SPEC ADD_STATIC_LIBUBSAN_LIBS +#elif defined(HAVE_LD_STATIC_DYNAMIC) +#define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \ + "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \ + ADD_STATIC_LIBUBSAN_LIBS +#else +#define LIBUBSAN_SPEC "-lubsan" ADD_STATIC_LIBUBSAN_LIBS +#endif +#endif + +#ifndef LIBUBSAN_EARLY_SPEC +#define LIBUBSAN_EARLY_SPEC "" +#endif + /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is included. */ #ifndef LIBGCC_SPEC @@ -714,7 +736,8 @@ proper position among the other output f #ifndef SANITIZER_EARLY_SPEC #define SANITIZER_EARLY_SPEC "\ %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \ - %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "}}}" + %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \ + %{%:sanitize(undefined):" LIBUBSAN_EARLY_SPEC "}}}" #endif /* Linker command line options for -fsanitize= late on the command line. */ @@ -724,7 +747,8 @@ proper position among the other output f %{static:%ecannot specify -static with -fsanitize=address}\ %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\ %{%:sanitize(thread):" LIBTSAN_SPEC "\ - %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}}}" + %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\ + %{%:sanitize(undefined):" LIBUBSAN_SPEC "}}}" #endif /* -u* was put back because both BSD and SysV seem to support it. */ --- gcc/testsuite/lib/ubsan-dg.exp.mp 2013-07-14 20:19:05.445091076 +0200 +++ gcc/testsuite/lib/ubsan-dg.exp 2013-07-15 04:25:00.476445749 +0200 @@ -0,0 +1,104 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# +# ubsan_link_flags -- compute library path and flags to find libubsan. +# (originally from g++.exp) +# + +proc ubsan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.a"] + || [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ubsan/ " + append flags " -L${gccpath}/libsanitizer/ubsan/.libs" + append ld_library_path ":${gccpath}/libsanitizer/ubsan/.libs" + } + } else { + global tool_root_dir + + set libubsan [lookfor_file ${tool_root_dir} libubsan] + if { $libubsan != "" } { + append flags "-L${libubsan} " + append ld_library_path ":${libubsan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# ubsan_init -- called at the start of each subdir of tests +# + +proc ubsan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global ubsan_saved_TEST_ALWAYS_FLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[ubsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[ubsan_link_flags [get_multilibs]]" + } + } + + if [info exists TEST_ALWAYS_FLAGS] { + set ubsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags" + } + } + if { $link_flags != "" } { + return 1 + } + return 0 +} + +# +# ubsan_finish -- called at the start of each subdir of tests +# + +proc ubsan_finish { args } { + global TEST_ALWAYS_FLAGS + global ubsan_saved_TEST_ALWAYS_FLAGS + + if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } +} --- gcc/testsuite/g++.dg/ubsan/ubsan.exp.mp 2013-07-15 04:23:57.350195021 +0200 +++ gcc/testsuite/g++.dg/ubsan/ubsan.exp 2013-07-15 04:25:41.662610652 +0200 @@ -0,0 +1,34 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Load support procs. +load_lib g++-dg.exp +load_lib ubsan-dg.exp + +# Initialize `dg'. +dg-init +if [ubsan_init] { + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/ubsan/*.c]] "" + +} + +# All done. +ubsan_finish +dg-finish --- gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C.mp 2013-07-15 08:50:26.786626970 +0200 +++ gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C 2013-07-15 08:50:42.852684617 +0200 @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w -std=c++11" } */ + +int +main (void) +{ + int a = 1; + a <<= 31; +} --- gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C.mp 2013-07-15 08:58:40.648302392 +0200 +++ gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C 2013-07-15 09:00:08.169601202 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w -std=c++11" } */ + +int +main (void) +{ + int a = -42; + a <<= 1; +} +/* { dg-output "left shift of negative value -42" } */ --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c.mp 2013-07-15 05:06:26.069422162 +0200 +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c 2013-07-15 08:00:25.517263218 +0200 @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-overflow" } */ + +#include + +int +main (void) +{ + INT_MIN / -1; + return 0; +} + /* { dg-output "division of -2147483648 by -1 cannot be represented in type int" } */ --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c.mp 2013-07-15 04:56:34.640124598 +0200 +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c 2013-07-15 07:59:58.713250028 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero" } */ + +int +main (void) +{ + 0 / 0; + return 0; +} + /* { dg-output "division by zero" } */ --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c.mp 2013-07-15 05:06:32.331446996 +0200 +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c 2013-07-15 05:26:00.450043589 +0200 @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-overflow" } */ + +#include + +int +main (void) +{ + /* This should not fail. */ + return (unsigned int) INT_MIN / -1; +} --- gcc/testsuite/c-c++-common/ubsan/shift-3.c.mp 2013-07-15 08:55:51.786698656 +0200 +++ gcc/testsuite/c-c++-common/ubsan/shift-3.c 2013-07-15 09:06:12.325948616 +0200 @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w" } */ + +int +main (void) +{ + unsigned int a = 1; + a <<= 31; + a <<= 1; + return 0; +} --- gcc/testsuite/c-c++-common/ubsan/unreachable-1.c.mp 2013-07-15 04:23:03.799985724 +0200 +++ gcc/testsuite/c-c++-common/ubsan/unreachable-1.c 2013-07-15 08:08:26.949168293 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=unreachable" } */ +/* { dg-shouldfail "ubsan" } */ + +int +main (void) +{ + __builtin_unreachable (); +} + /* { dg-output "execution reached a __builtin_unreachable\\(\\) call" } */ --- gcc/testsuite/c-c++-common/ubsan/shift-1.c.mp 2013-07-15 05:30:50.662201212 +0200 +++ gcc/testsuite/c-c++-common/ubsan/shift-1.c 2013-07-15 08:55:12.915542820 +0200 @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w" } */ + +int +main (void) +{ + int a = 1; + a <<= 152; + return 0; +} +/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type int" } */ --- gcc/testsuite/c-c++-common/ubsan/shift-2.c.mp 2013-07-15 06:36:50.754358414 +0200 +++ gcc/testsuite/c-c++-common/ubsan/shift-2.c 2013-07-15 07:59:13.770070848 +0200 @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w" } */ + +int +main (void) +{ + int a = 1; + a <<= -3; + return 0; +} +/* { dg-output "shift exponent -3 is negative" } */ --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c.mp 2013-07-15 05:02:33.252507624 +0200 +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c 2013-07-15 08:00:10.452296766 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero" } */ + +int +main (void) +{ + 1UL / 0; + return 0; +} + /* { dg-output "division by zero" } */ --- gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c.mp 2013-07-15 08:47:01.177890666 +0200 +++ gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c 2013-07-15 08:48:39.085243951 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w -std=c99" } */ + +int +main (void) +{ + int a = 1; + a <<= 31; +} +/* { dg-output "left shift of 1 by 31 places cannot be represented in type int" } */ --- gcc/testsuite/gcc.dg/ubsan/ubsan.exp.mp 2013-07-14 20:17:20.856743632 +0200 +++ gcc/testsuite/gcc.dg/ubsan/ubsan.exp 2013-07-15 01:44:18.316194533 +0200 @@ -0,0 +1,36 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp +load_lib ubsan-dg.exp + +# Initialize `dg'. +dg-init +if [ubsan_init] { + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/ubsan/*.c]] "" + +} + +# All done. +ubsan_finish +dg-finish --- gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c.mp 2013-07-15 08:42:03.829843562 +0200 +++ gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c 2013-07-15 08:43:20.769105362 +0200 @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w -std=c99" } */ + +int +main (void) +{ + int a = -42; + a << 1; +} +/* { dg-output "left shift of negative value -42" } */