From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2181 invoked by alias); 13 May 2019 22:07:53 -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 2173 invoked by uid 89); 13 May 2019 22:07:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.0 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Per, classc, UD:class.c, class.c 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 ESMTP; Mon, 13 May 2019 22:07:51 +0000 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 44057C079C29 for ; Mon, 13 May 2019 22:07:50 +0000 (UTC) Received: from redhat.com (ovpn-120-210.rdu2.redhat.com [10.10.120.210]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AB1391001E65; Mon, 13 May 2019 22:07:49 +0000 (UTC) Date: Mon, 13 May 2019 22:07:00 -0000 From: Marek Polacek To: GCC Patches , Jason Merrill Subject: C++ PATCH for CWG 2096, constraints on literal unions Message-ID: <20190513220747.GH20687@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.11.4 (2019-03-13) X-SW-Source: 2019-05/txt/msg00648.txt.bz2 This patch implements CWG 2096 which relaxes the constraints for literal unions. [basic.types]/p10 now says: A type is a literal type if... -- it is a union, at least one of its non-static data members is of non-volatile literal type, [...] check_field_decls is called with CLASSTYPE_LITERAL_P set to true, so we can re-set it after we've processed all fields. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-05-13 Marek Polacek CWG 2096 - constraints on literal unions. * class.c (check_field_decls): Initialize booleans directly. A union is literal if at least one of its non-static data members is of non-volatile literal type. * g++.dg/cpp0x/literal-type1.C: New test. diff --git gcc/cp/class.c gcc/cp/class.c index a47777cdd9e..ed885a5a2c1 100644 --- gcc/cp/class.c +++ gcc/cp/class.c @@ -3403,18 +3403,19 @@ check_field_decls (tree t, tree *access_decls, { tree *field; tree *next; - bool has_pointers; - bool any_default_members; int cant_pack = 0; int field_access = -1; /* Assume there are no access declarations. */ *access_decls = NULL_TREE; /* Assume this class has no pointer members. */ - has_pointers = false; + bool has_pointers = false; /* Assume none of the members of this class have default initializations. */ - any_default_members = false; + bool any_default_members = false; + /* Assume none of the non-static data members are of non-volatile literal + type. */ + bool found_nv_literal_p = false; for (field = &TYPE_FIELDS (t); *field; field = next) { @@ -3498,13 +3499,19 @@ check_field_decls (tree t, tree *access_decls, if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) CLASSTYPE_NON_AGGREGATE (t) = 1; - /* If at least one non-static data member is non-literal, the whole - class becomes non-literal. Per Core/1453, volatile non-static - data members and base classes are also not allowed. + /* If it is not a union and at least one non-static data member is + non-literal, the whole class becomes non-literal. Per Core/1453, + volatile non-static data members and base classes are also not allowed. + If it is a union, we might set CLASSTYPE_LITERAL_P after we've seen all + members. Note: if the type is incomplete we will complain later on. */ - if (COMPLETE_TYPE_P (type) - && (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type))) - CLASSTYPE_LITERAL_P (t) = false; + if (COMPLETE_TYPE_P (type)) + { + if (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type)) + CLASSTYPE_LITERAL_P (t) = false; + else + found_nv_literal_p = true; + } /* A standard-layout class is a class that: ... @@ -3677,6 +3684,11 @@ check_field_decls (tree t, tree *access_decls, "field %q#D with same name as class", x); } + /* Per CWG 2096, a type is a literal type if it is a union, and at least + one of its non-static data members is of non-volatile literal type. */ + if (TREE_CODE (t) == UNION_TYPE && found_nv_literal_p) + CLASSTYPE_LITERAL_P (t) = true; + /* Effective C++ rule 11: if a class has dynamic memory held by pointers, it should also define a copy constructor and an assignment operator to implement the correct copy semantic (deep vs shallow, etc.). As it is diff --git gcc/testsuite/g++.dg/cpp0x/literal-type1.C gcc/testsuite/g++.dg/cpp0x/literal-type1.C new file mode 100644 index 00000000000..7b5d4288923 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/literal-type1.C @@ -0,0 +1,54 @@ +// CWG 2096 - constraints on literal unions. +// { dg-do compile { target c++11 } } + +struct literal { }; +typedef volatile int nonliteral_v; +struct nonliteral { + nonliteral() {} +}; + +union U { + literal l; + nonliteral n; + + constexpr U() : l{} {} +}; + +constexpr U u{}; + +union U2 { + nonliteral n; + literal l; + + constexpr U2() : l{} {} +}; + +constexpr U2 u2{}; + +union U3 { // { dg-message "not literal" } + nonliteral_v n; // { dg-message "volatile type" } + + constexpr U3() : n{} {} +}; + +constexpr U3 u3{}; // { dg-error "not literal" } + +union U4 { + nonliteral n; + nonliteral_v n2; + literal l; + nonliteral n3; + + constexpr U4() : l{} {} +}; + +constexpr U4 u4{}; + +union U5 { + nonliteral_v n; + literal l; + + constexpr U5() : n{} {} +}; + +constexpr U5 u5{};