From patchwork Wed Oct 14 16:21:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 530257 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B314B140FDA for ; Thu, 15 Oct 2015 03:21:57 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=vNONS/t/; dkim-atps=neutral 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:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=a8Kpem5PZhv9MzGRR4btKkaUwUyLEozqYqBZMqvXmAn R1EdL235xzd0/KdSJMzP25g8OB9Wik9mNkFBXJrHHWKL3C4ACKwwQ5mQI6wCbRim Zxq5zJLlFwfQzN3M8WmEHyQp0sFmLIA2r4JMeJd+udqwAgESq5Q18tnMkghhK5IE = 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:subject:message-id:reply-to:mime-version:content-type; s=default; bh=3hFvx480JJdxlhBCnacQHE2LKX4=; b=vNONS/t/CTngcoRI/ LnjZ84CUenbkM+ykIVhHh0LD8TxRmAg+/A4MZUFgVt9CkSqQpZFuukE6+/y4hh2P QPAy5n/j7MoPu718jAyfonstiSUan4CkS2g3Hl12mEKCIVTn/YbAMwExLc9EDVPz B8tt9EvidUSr2bwTymgGWNGODw= Received: (qmail 81508 invoked by alias); 14 Oct 2015 16:21:50 -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 81498 invoked by uid 89); 14 Oct 2015 16:21:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mga11.intel.com Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Oct 2015 16:21:48 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 14 Oct 2015 09:21:47 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([172.25.70.52]) by FMSMGA003.fm.intel.com with ESMTP; 14 Oct 2015 09:21:46 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 1000) id F21E5C3C83; Wed, 14 Oct 2015 09:21:46 -0700 (PDT) Date: Wed, 14 Oct 2015 09:21:46 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Subject: [PATCH] PR middle-end/67220: GCC fails to properly handle libcall symbol visibility of built functions Message-ID: <20151014162146.GA24833@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) By default, there is no visibility on builtin functions. When there is explicitly declared visibility on the C library function which a builtin function fall back on, we should honor the explicit visibility on the the C library function. There are 2 issues: 1. We never update visibility of the fall back C library function. 2. init_block_move_fn and init_block_clear_fn used to implement builtin memcpy and memset generate the library call to memcpy and memset directly without checking if there is explicitly declared visibility on them. This patch updates builtin function with explicit visibility and checks visibility on builtin memcpy/memset when generating library call. Tested on Linux/x86-64 without regressions. OK for trunk? H.J. --- gcc/c/ PR middle-end/67220 * c-decl.c (diagnose_mismatched_decls): Copy explicit visibility to builtin function. gcc/ PR middle-end/67220 * expr.c (init_block_move_fn): Copy visibility from the builtin memcpy. (init_block_clear_fn): Copy visibility from the builtin memset. gcc/testsuite/ PR middle-end/67220 * gcc.target/i386/pr67220-1.c: New test. * gcc.target/i386/pr67220-2.c: Likewise. * gcc.target/i386/pr67220-3.c: Likewise. * gcc.target/i386/pr67220-4.c: Likewise. * gcc.target/i386/pr67220-5.c: Likewise. * gcc.target/i386/pr67220-6.c: Likewise. --- gcc/c/c-decl.c | 21 +++++++++++++++++---- gcc/expr.c | 12 ++++++++++-- gcc/testsuite/gcc.target/i386/pr67220-1.c | 15 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr67220-2.c | 15 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr67220-3.c | 15 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr67220-4.c | 15 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr67220-5.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/i386/pr67220-6.c | 14 ++++++++++++++ 8 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-3.c create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-4.c create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr67220-6.c diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index ce8406a..26460eb 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2232,11 +2232,24 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* warnings */ /* All decls must agree on a visibility. */ if (CODE_CONTAINS_STRUCT (TREE_CODE (newdecl), TS_DECL_WITH_VIS) - && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl) - && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) + && DECL_VISIBILITY_SPECIFIED (newdecl)) { - warned |= warning (0, "redeclaration of %q+D with different visibility " - "(old visibility preserved)", newdecl); + if (DECL_VISIBILITY_SPECIFIED (olddecl)) + { + if (DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) + warned |= warning (0, "redeclaration of %q+D with different " + "visibility (old visibility preserved)", + newdecl); + } + else if (TREE_CODE (olddecl) == FUNCTION_DECL + && DECL_BUILT_IN (olddecl)) + { + enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl); + tree fndecl = builtin_decl_explicit (fncode); + gcc_assert (fndecl && !DECL_VISIBILITY_SPECIFIED (fndecl)); + DECL_VISIBILITY (fndecl) = DECL_VISIBILITY (newdecl); + DECL_VISIBILITY_SPECIFIED (fndecl) = 1; + } } if (TREE_CODE (newdecl) == FUNCTION_DECL) diff --git a/gcc/expr.c b/gcc/expr.c index 595324d..a12db96 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1390,7 +1390,11 @@ init_block_move_fn (const char *asmspec) TREE_PUBLIC (fn) = 1; DECL_ARTIFICIAL (fn) = 1; TREE_NOTHROW (fn) = 1; - DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; + tree fndecl = builtin_decl_explicit (BUILT_IN_MEMCPY); + if (fndecl) + DECL_VISIBILITY (fn) = DECL_VISIBILITY (fndecl); + else + DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; DECL_VISIBILITY_SPECIFIED (fn) = 1; attr_args = build_tree_list (NULL_TREE, build_string (1, "1")); @@ -2846,7 +2850,11 @@ init_block_clear_fn (const char *asmspec) TREE_PUBLIC (fn) = 1; DECL_ARTIFICIAL (fn) = 1; TREE_NOTHROW (fn) = 1; - DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; + tree fndecl = builtin_decl_explicit (BUILT_IN_MEMSET); + if (fndecl) + DECL_VISIBILITY (fn) = DECL_VISIBILITY (fndecl); + else + DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; DECL_VISIBILITY_SPECIFIED (fn) = 1; block_clear_fn = fn; diff --git a/gcc/testsuite/gcc.target/i386/pr67220-1.c b/gcc/testsuite/gcc.target/i386/pr67220-1.c new file mode 100644 index 0000000..06af0ed --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *memcpy (void *, const void *, size_t); +extern void *memcpy (void *, const void *, size_t) + __attribute__ ((visibility ("hidden"))); + +void +bar (void *d, void *s, size_t n) +{ + memcpy (d, s, n); +} + +/* { dg-final { scan-assembler-not "memcpy@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67220-2.c b/gcc/testsuite/gcc.target/i386/pr67220-2.c new file mode 100644 index 0000000..71e1d1e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *memset (void *, int, size_t); +extern void *memset (void *, int, size_t) + __attribute__ ((visibility ("hidden"))); + +void +bar (void *s, size_t n) +{ + memset (s, '\0', n); +} + +/* { dg-final { scan-assembler-not "memset@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67220-3.c b/gcc/testsuite/gcc.target/i386/pr67220-3.c new file mode 100644 index 0000000..fa54530 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *memcpy (void *, const void *, size_t) + __attribute__ ((visibility ("hidden"))); +extern void *memcpy (void *, const void *, size_t); + +void +bar (void *d, void *s, size_t n) +{ + __builtin_memcpy (d, s, n); +} + +/* { dg-final { scan-assembler-not "memcpy@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67220-4.c b/gcc/testsuite/gcc.target/i386/pr67220-4.c new file mode 100644 index 0000000..9ce02f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-4.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *memset (void *, int, size_t) + __attribute__ ((visibility ("hidden"))); +extern void *memset (void *, int, size_t); + +void +bar (void *s, size_t n) +{ + __builtin_memset (s, '\0', n); +} + +/* { dg-final { scan-assembler-not "memset@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67220-5.c b/gcc/testsuite/gcc.target/i386/pr67220-5.c new file mode 100644 index 0000000..e2c8ba3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +extern int strcmp (const char *, const char *); +extern int strcmp (const char *, const char *) + __attribute__ ((visibility ("hidden"))); + +int +bar (const char *d, const char *s) +{ + return __builtin_strcmp (d, s); +} + +/* { dg-final { scan-assembler-not "strcmp@PLT" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr67220-6.c b/gcc/testsuite/gcc.target/i386/pr67220-6.c new file mode 100644 index 0000000..c83d4c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67220-6.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fPIC" } */ + +extern int strcmp (const char *, const char *) + __attribute__ ((visibility ("hidden"))); +extern int strcmp (const char *, const char *); + +int +bar (const char *d, const char *s) +{ + return __builtin_strcmp (d, s); +} + +/* { dg-final { scan-assembler-not "strcmp@PLT" } } */