From patchwork Sat Aug 5 16:33:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Uecker X-Patchwork-Id: 1817332 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.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=HnuYn+WG; dkim-atps=neutral Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RJ7SN2mF8z1yYD for ; Sun, 6 Aug 2023 02:33:38 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A001C385840F for ; Sat, 5 Aug 2023 16:33:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A001C385840F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691253216; bh=SYPxjI+izmghRzFaoeoljMUI6LRurmfpWceWu7XUAiY=; h=Subject:To:Cc:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=HnuYn+WGGrUvNdXyxc4ZeQD6mTgOZD5inLp79sFIe5V7le0Jqcw5mL7gbLcoKMesJ G+6id+JhezSjCAHsWU41HPybEYTsYTXsfpfg0isnqVQQLtZCi8eFmzxRbCc4eMQVOB GRRFKCVWwMLAcgAUdVyh63I75V0wlaVlpRnfVTbA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailrelay.tugraz.at (mailrelay.tugraz.at [129.27.2.202]) by sourceware.org (Postfix) with ESMTPS id B57B23858D35 for ; Sat, 5 Aug 2023 16:33:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B57B23858D35 Received: from vra-169-214.tugraz.at (vra-169-214.tugraz.at [129.27.169.214]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4RJ7Rh4RGpz3wgY; Sat, 5 Aug 2023 18:33:04 +0200 (CEST) Message-ID: Subject: [C PATCH] Support typename as selector in _Generic To: gcc-patches@gcc.gnu.org Cc: Joseph Myers Date: Sat, 05 Aug 2023 18:33:04 +0200 User-Agent: Evolution 3.38.3-1+deb11u2 MIME-Version: 1.0 X-TUG-Backscatter-control: G/VXY7/6zeyuAY/PU2/0qw X-Spam-Scanner: SpamAssassin 3.003001 X-Spam-Score-relay: -1.9 X-Scanned-By: MIMEDefang 2.74 on 129.27.10.116 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, 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: , X-Patchwork-Original-From: Martin Uecker via Gcc-patches From: Martin Uecker Reply-To: Martin Uecker Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Clang now has an extension which accepts a typename for _Generic. This is simple to implement and is useful. Do we want this? Clang calls it a "Clang extension" in the pedantic warning. I changed it to "an extension" I am not sure what the policy is. Do we need an extra warning option? Clang has one. No documentation so far. Bootstrapped and regression tested on x86_64-pc-linux-gnu. Martin c: Support typename as selector in _Generic Support typenames as first argument to _Generic which is an extension supported by Clang. It makes it easier to test for types with qualifiers in combination with typeof. gcc/c/: * c-parser.cc (c_parser_generic_selection): Support typename in _Generic selector. gcc/testsuite/: * gnu2x-generic.c: New test. diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 57a01dc2fa3..9aea2425294 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -9312,30 +9312,51 @@ c_parser_generic_selection (c_parser *parser) if (!parens.require_open (parser)) return error_expr; - c_inhibit_evaluation_warnings++; selector_loc = c_parser_peek_token (parser)->location; - selector = c_parser_expr_no_commas (parser, NULL); - selector = default_function_array_conversion (selector_loc, selector); - c_inhibit_evaluation_warnings--; - if (selector.value == error_mark_node) + if (c_token_starts_typename (c_parser_peek_token (parser))) { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - return selector; - } - mark_exp_read (selector.value); - selector_type = TREE_TYPE (selector.value); - /* In ISO C terms, rvalues (including the controlling expression of - _Generic) do not have qualified types. */ - if (TREE_CODE (selector_type) != ARRAY_TYPE) - selector_type = TYPE_MAIN_VARIANT (selector_type); - /* In ISO C terms, _Noreturn is not part of the type of expressions - such as &abort, but in GCC it is represented internally as a type - qualifier. */ - if (FUNCTION_POINTER_TYPE_P (selector_type) - && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED) - selector_type - = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type))); + /* Language extension introduced by Clang. */ + pedwarn (selector_loc, OPT_Wpedantic, "passing a type argument as " + "first argument to %<_Generic%> is an extension"); + struct c_type_name *type_name; + c_inhibit_evaluation_warnings++; + type_name = c_parser_type_name (parser); + c_inhibit_evaluation_warnings--; + if (NULL == type_name) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return error_expr; + } + /* Qualifiers are preserved. */ + selector_type = groktypename (type_name, NULL, NULL); + } + else + { + c_inhibit_evaluation_warnings++; + selector = c_parser_expr_no_commas (parser, NULL); + selector = default_function_array_conversion (selector_loc, selector); + c_inhibit_evaluation_warnings--; + + if (selector.value == error_mark_node) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return selector; + } + mark_exp_read (selector.value); + selector_type = TREE_TYPE (selector.value); + /* In ISO C terms, rvalues (including the controlling expression of + _Generic) do not have qualified types. */ + if (TREE_CODE (selector_type) != ARRAY_TYPE) + selector_type = TYPE_MAIN_VARIANT (selector_type); + /* In ISO C terms, _Noreturn is not part of the type of expressions + such as &abort, but in GCC it is represented internally as a type + qualifier. */ + if (FUNCTION_POINTER_TYPE_P (selector_type) + && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED) + selector_type + = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type))); + } if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) { @@ -9401,7 +9422,7 @@ c_parser_generic_selection (c_parser *parser) assoc.expression = c_parser_expr_no_commas (parser, NULL); if (!match) - c_inhibit_evaluation_warnings--; + c_inhibit_evaluation_warnings--; if (assoc.expression.value == error_mark_node) { diff --git a/gcc/testsuite/gcc.dg/gnu2x-generic.c b/gcc/testsuite/gcc.dg/gnu2x-generic.c new file mode 100644 index 00000000000..82b09578072 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu2x-generic.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +_Static_assert(_Generic(const int, const int: 1, int: 0), ""); +_Static_assert(_Generic( int, const int: 0, int: 1), ""); +_Static_assert(_Generic(int[4], int[4]: 1), ""); +_Static_assert(_Generic(typeof(int[4]), int[4]: 1), ""); + +void foo(int n) +{ + _Static_assert(_Generic(int[n++], int[4]: 1), ""); +} + +#pragma GCC diagnostic warning "-Wpedantic" +_Static_assert(_Generic(int[4], int[4]: 1), ""); /* { dg-warning "extension" } */ + +