From patchwork Fri Feb 10 00:43:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 55171 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp664713wrn; Thu, 9 Feb 2023 16:44:11 -0800 (PST) X-Google-Smtp-Source: AK7set++Inre7gym7dHIGzgV7Qo599wsHVhrAYYRj8o1Jn8jmdG6YYXrYYO7mQ7ALuL+TZymCsxm X-Received: by 2002:a17:906:919:b0:883:fe6b:814 with SMTP id i25-20020a170906091900b00883fe6b0814mr12613017ejd.37.1675989851232; Thu, 09 Feb 2023 16:44:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675989851; cv=none; d=google.com; s=arc-20160816; b=yEwF33PH8ytCKlmdNr9k/x1FLJbMjw86FdOX7RlJcyAkMMnel6u4aH4E0AllJrLwZF rvXb6yvP58bzXLQF0gLn+ScLujedKX7JMs0pgOIunwgOuOfT8Z9nvt9NVUqg3a/vsNHp O63z8ipYqrGUeN3sMtKAuHdNKfQc8lBpWldM8EYAGTNQ0mLb9d9sXcpwgFrH07X2t9xW cmnQwEyfRiueT3J0Ex/1H5aNh8tnlrAbnJvxFBlwjHRXb+NibI9yuWbLjE5jEZdzsUAP 1sLUJH4D4VTcrXbldP36DLii+XAEX59BwQkzX6VpIVa0nQOBYE9Agd/GM6wmp0hf+xUg N3sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mime-version:message-id:subject :to:from:date:ironport-sdr:dmarc-filter:delivered-to; bh=J1EVoH20UPJ9/wnrFMLkNPx549pjTugB3FdHbdsBCDY=; b=eXkNLmzSc9/7DdZKixu6OSfh4RyrTfRaUAsvg4ATBVhSCLn/p2IokLxCgUGivDlJ9S Owxg2vobuwZk8iDcbK8v/aEjkMCyMaU0jaw5GRabJE+T9XJauTr4H9j224z0/sJQkiEI 9uVnQzUgt8+052zvqbaKbOGzGY5JnwubrWXdrzt3Zxvy4yuThyQW2g2KBBQyo1/hQZE5 V79tDHejG146P4XuFwYxORYJhk44sUnO/s4rYJZdtg1xNDbzYF0i544rn9jJSkTLI84F 4AQ2W6gSZ4tss0CZelBuYMehDLMCZMIV3ijoptBEVNUUzjsXeW3KujKyDJqWlhswfBZD GKAg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id f4-20020a1709063f4400b0088f0f4cb7f7si3884491ejj.931.2023.02.09.16.44.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Feb 2023 16:44:11 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 89C3938555A0 for ; Fri, 10 Feb 2023 00:44:01 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) by sourceware.org (Postfix) with ESMTPS id B03123858C50 for ; Fri, 10 Feb 2023 00:43:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B03123858C50 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.97,285,1669104000"; d="scan'208";a="100254017" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 09 Feb 2023 16:43:31 -0800 IronPort-SDR: LxbJNUjsVQ/Ci396iYt1H6PXyVLf/H8Zh0C8csj21flKj6QCVkZt72+Txoz+XZnqYcnoAGfJd2 68AWzPe5I7OHB/Xrib0iPfFjTOBrucsbwDakqudjo1QQ1jDN2eznIPEwPQQOCNKCSnx9bDwi1m k4OvZLRSCJJ2MOPesYGCcIZWap5LcqfnRuzCLi3Da2K0HUHMopYfvvCqVSxhFBFpGU1JmOT1fX CW8VzR13awpNMTlJTyd3ZgKFmj4oCbrHO8ARSfeOA8A58AMs1BRaT0FCedV332X43eLYNToiH9 TE8= Date: Fri, 10 Feb 2023 00:43:27 +0000 From: Joseph Myers To: Subject: [committed] c: Allow conversions of null pointer constants to nullptr_t Message-ID: MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-13.mgc.mentorg.com (139.181.222.13) To svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) X-Spam-Status: No, score=-3114.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757402734380285275?= X-GMAIL-MSGID: =?utf-8?q?1757402734380285275?= WG14 has agreed to allow conversions (explicit and implicit) from null pointer constants to nullptr_t; update GCC's nullptr_t implementation to match. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ * c-convert.cc (c_convert): Allow conversion of a null pointer constant to nullptr_t. * c-typeck.cc (null_pointer_constant_p): Remove static. (convert_for_assignment): Allow conversion of a null pointer constant to nullptr_t. (digest_init): Handle NULLPTR_TYPE among scalar conversions. * c-tree.h (null_pointer_constant_p): Declare. gcc/testsuite/ * gcc.dg/c2x-nullptr-1.c: Test conversion of null pointer constants to nullptr_t. * gcc.dg/c2x-nullptr-3.c: Do not expect errors for conversion of null pointer constants to nullptr_t. Do test errors for conversion of other values to nullptr_t and for unary '+' on nullptr_t. diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc index dccd245dfc3..0f35dc4fe9a 100644 --- a/gcc/c/c-convert.cc +++ b/gcc/c/c-convert.cc @@ -157,6 +157,19 @@ c_convert (tree type, tree expr, bool init_const) ret = convert_to_pointer (type, e); goto maybe_fold; + case NULLPTR_TYPE: + /* A null pointer constant or value of type nullptr_t may be + converted to nullptr_t. The latter case has already been + handled. build_c_cast will create an additional NOP_EXPR to + ensure the result of the conversion is not itself a null + pointer constant. */ + if (null_pointer_constant_p (expr)) + { + ret = build_int_cst (type, 0); + goto maybe_fold; + } + break; + case REAL_TYPE: ret = convert_to_real (type, e); goto maybe_fold; @@ -201,12 +214,14 @@ c_convert (tree type, tree expr, bool init_const) } /* If we are converting to nullptr_t, don't say "non-scalar type" because - the nullptr_t type is a scalar type. Only nullptr_t shall be converted - to nullptr_t. */ + the nullptr_t type is a scalar type. Only nullptr_t or a null pointer + constant shall be converted to nullptr_t. */ if (code == NULLPTR_TYPE) { error ("conversion from %qT to %qT", TREE_TYPE (e), type); - inform (input_location, "only %qT can be converted to %qT", type, type); + inform (input_location, + "only %qT or a null pointer constant can be converted to %qT", + type, type); } else error ("conversion to non-scalar type requested"); diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 00ccf87e6e6..e5eefe6bbba 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -728,6 +728,7 @@ extern location_t c_last_sizeof_loc; extern struct c_switch *c_switch_stack; +extern bool null_pointer_constant_p (const_tree); extern bool char_type_p (tree); extern tree c_objc_common_truthvalue_conversion (location_t, tree); extern tree require_complete_type (location_t, tree); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 157b77eda95..e37b0973cd6 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -89,7 +89,6 @@ static bool require_constant_value; static bool require_constant_elements; static bool require_constexpr_value; -static bool null_pointer_constant_p (const_tree); static tree qualify_type (tree, tree); static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *, bool *); @@ -130,7 +129,7 @@ static int comptypes_internal (const_tree, const_tree, bool *, bool *); /* Return true if EXP is a null pointer constant, false otherwise. */ -static bool +bool null_pointer_constant_p (const_tree expr) { /* This should really operate on c_expr structures, but they aren't @@ -7837,6 +7836,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, in_late_binary_op = save; return ret; } + else if (codel == NULLPTR_TYPE && null_pointer_constant) + return convert (type, rhs); switch (errtype) { @@ -8596,7 +8597,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, if (code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE - || code == COMPLEX_TYPE || code == VECTOR_TYPE) + || code == COMPLEX_TYPE || code == VECTOR_TYPE || code == NULLPTR_TYPE) { tree unconverted_init = inside_init; if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c index 04f9901bb12..4e440234d52 100644 --- a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c +++ b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c @@ -11,8 +11,9 @@ void f2 (int *) { } void f3 (_Bool) { } nullptr_t cmp (void) { return nullptr; } -/* The type nullptr_t shall not be converted to any type other than void, bool or - a pointer type. No type other than nullptr_t shall be converted to nullptr_t. */ +/* The type nullptr_t shall not be converted to any type other than void, bool + or a pointer type. No type other than nullptr_t or a null pointer constant + shall be converted to nullptr_t. */ void test1 (void) { @@ -63,6 +64,17 @@ test1 (void) (void) np2; (void) cmp (); (void)(nullptr_t) nullptr; + + const nullptr_t n = 0; + (void) (nullptr_t) 0; + + f1 (0); + f1 ((void *) 0); + f1 (0L); + nullptr_t n2; + n2 = (void *) 0; + n2 = 123 - 123; + (void) n2; } /* Test valid comparison. */ diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c index 591ab7e6158..09d9856ef97 100644 --- a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c +++ b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c @@ -29,21 +29,24 @@ test2 (void) float d = nullptr; /* { dg-error "incompatible types" } */ char arr[10] = { nullptr }; /* { dg-error "incompatible types" } */ - /* No type other than nullptr_t shall be converted to nullptr_t. */ - const nullptr_t n = 0; /* { dg-error "invalid initializer" } */ - +(nullptr_t) 0; /* { dg-error "conversion from .int. to .nullptr_t." } */ - - g (0); /* { dg-error "incompatible type" } */ + /* Unary '+' is not valid for nullptr. */ + +nullptr; /* { dg-error "wrong type argument to unary plus" } */ + g (0.0); /* { dg-error "incompatible type" } */ + g (1); /* { dg-error "incompatible type" } */ + g ((int) (float) 0.0); /* { dg-error "incompatible type" } */ int i = 42 + nullptr; /* { dg-error "invalid operands" } */ /* The assignment of an object of type nullptr_t with a value of another - type, even if the value is a null pointer constant, is a constraint + type, other than a null pointer constant, is a constraint violation. */ nullptr_t m; - m = 0; /* { dg-error "incompatible types" } */ + m = 1; /* { dg-error "incompatible types" } */ + m = 0.0; /* { dg-error "incompatible types" } */ (void) m; - nullptr_t o = 0; /* { dg-error "invalid initializer" } */ + nullptr_t o = 1; /* { dg-error "incompatible types" } */ + (nullptr_t) 0.0; /* { dg-error "conversion" } */ + (nullptr_t) (int) (float) 0.0; /* { dg-error "conversion" } */ switch (nullptr); /* { dg-error "switch quantity not an integer" } */ }