From patchwork Wed Apr 29 20:59:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1279690 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=wFQJJQ4i; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49C9rS4RfDz9sSK for ; Thu, 30 Apr 2020 07:00:06 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0558D389365B; Wed, 29 Apr 2020 21:00:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0558D389365B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1588194004; bh=j2r1NmECi5FtQeW/PCNj042uAyv23XOyy/izamsqRb8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=wFQJJQ4ioh4zXqNIX9dX89TbIXHBW+2gMP+0nET5wm+sSMn/1ClGXPRgFcnRQTnqs 3mffjJQNVNLfekzOvB9r7M/i4Dx2rv3zgH5C8HTVhx6NdV0pOQeGjOSV5I6ORVIhqj I29Nq2X9+czjRvNC8jYHX1BR/28rmjTHizW7rMTU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by sourceware.org (Postfix) with ESMTP id A537138930CB for ; Wed, 29 Apr 2020 21:00:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A537138930CB Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-250-ZRyloKBEP4KF--A6pzgMNQ-1; Wed, 29 Apr 2020 16:59:58 -0400 X-MC-Unique: ZRyloKBEP4KF--A6pzgMNQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A4266462 for ; Wed, 29 Apr 2020 20:59:57 +0000 (UTC) Received: from pdp-11.redhat.com (ovpn-119-124.rdu2.redhat.com [10.10.119.124]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4BEB45C1BE for ; Wed, 29 Apr 2020 20:59:57 +0000 (UTC) To: GCC Patches Subject: [PATCH] tree: Don't reuse types if TYPE_USER_ALIGN differ [PR94775] Date: Wed, 29 Apr 2020 16:59:43 -0400 Message-Id: <20200429205943.2277840-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-28.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Here we trip on the TYPE_USER_ALIGN (t) assert in strip_typedefs: it gets "const d[0]" with TYPE_USER_ALIGN=0 but the result built by build_cplus_array_type is "const char[0]" with TYPE_USER_ALIGN=1. When we strip_typedefs the element of the array "const d", we see it's a typedef_variant_p, so we look at its DECL_ORIGINAL_TYPE, which is char, but we need to add the const qualifier, so we call cp_build_qualified_type -> build_qualified_type where get_qualified_type checks to see if we already have such a type by walking the variants list, which in this case is: char -> c -> const char -> const char -> d -> const d Because check_base_type only checks TYPE_ALIGN and not TYPE_USER_ALIGN, we choose the first const char, which has TYPE_USER_ALIGN set. If the element type of an array has TYPE_USER_ALIGN, the array type gets it too. So we can make check_base_type stricter. I was afraid that it might make us reuse types less often, but measuring showed that we build the same amount of types with and without the patch, while bootstrapping. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/9/8? PR c++/94775 * tree.c (check_base_type): Return true only if TYPE_USER_ALIGN match. (check_aligned_type): Check if TYPE_USER_ALIGN match. * g++.dg/warn/Warray-bounds-10.C: New test. --- gcc/testsuite/g++.dg/warn/Warray-bounds-10.C | 40 ++++++++++++++++++++ gcc/tree.c | 4 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/Warray-bounds-10.C base-commit: 8f1591763fd50b143af0dc1770741f326a97583a diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C new file mode 100644 index 00000000000..0a18f637e0e --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C @@ -0,0 +1,40 @@ +// PR c++/94775 +// { dg-do compile { target c++14 } } +// { dg-options "-O2 -Warray-bounds" } + +template using a = int; +template using b = int; +typedef char d; +template using e = int; +template struct h { using i = b>, e>; }; +template using j = typename h::i; +long ab, k, aj; +const d l[]{}; +class m { +public: + m(int); +}; +class n { + void ad() const; + template void o(long) const { + using c __attribute__((aligned(1))) = const ae; + } + long p; + template + auto s(unsigned long, unsigned long, unsigned long, unsigned long) const; + template auto q(unsigned long, unsigned long) const; +}; +template +auto n::s(unsigned long, unsigned long, unsigned long, unsigned long t) const { + o(p); + return t; +} +template auto n::q(unsigned long p1, unsigned long p2) const { + using r = j<4, false>; + using ai = j<4, g>; + return s(ab, k, p1, p2); +} +void n::ad() const { + long f(l[aj]); // { dg-warning "outside array bounds" } + m(q(8, f)); +} diff --git a/gcc/tree.c b/gcc/tree.c index e451401822c..341766c51e5 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6493,7 +6493,8 @@ check_base_type (const_tree cand, const_tree base) TYPE_ATTRIBUTES (base))) return false; /* Check alignment. */ - if (TYPE_ALIGN (cand) == TYPE_ALIGN (base)) + if (TYPE_ALIGN (cand) == TYPE_ALIGN (base) + && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base)) return true; /* Atomic types increase minimal alignment. We must to do so as well or we get duplicated canonical types. See PR88686. */ @@ -6528,6 +6529,7 @@ check_aligned_type (const_tree cand, const_tree base, unsigned int align) && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base) /* Check alignment. */ && TYPE_ALIGN (cand) == align + && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base) && attribute_list_equal (TYPE_ATTRIBUTES (cand), TYPE_ATTRIBUTES (base)) && check_lang_type (cand, base));