From patchwork Thu Feb 22 16:07:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 86228 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E4FFA385841C for ; Thu, 22 Feb 2024 16:08:48 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id DD3183858416 for ; Thu, 22 Feb 2024 16:08:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DD3183858416 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DD3183858416 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708618092; cv=none; b=BkqelR7vLvSUAgyWSV5R2FWHh5sR2gFVA5WEO+ByTrIKLK/0/1hfd4L2hM6X5XUO+TCziTVYsmZQYODDx2sJtjeXquphp5BYvXOdThonBmwCOqwzaBZyT85sr6fXi+uLKdV6XOXNDq8bvzo9L36Jh5a5WoeeYMdvrDv+Ar2gqcY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708618092; c=relaxed/simple; bh=ZBsLmpjtVh0n+inkxMvuWVWPyECPs2GhjM7aMplGt7M=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=prSdcOlld3Z+heUazOowV9g1qvmS2t/OEVjXG84B8GKuyDVEz5CnvZZNcBhIY8Y99KZ3tMzoZD6WzOTkMy+rlRT4XK2vMB/kUCa3YLbGyHe8rOnJFS4owe+YHtqkTwuk1HmErNxZEWq5Twk+gO4y3HV1Vhj5Y/gpHHJuM4Zbp2U= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1708618081; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=ctdwW+vJ2aY9/cn2TcdJF8aQMoGnhYtNJdQNvlYyyEM=; b=GnJkio7VMg+xk8QMuWyuwQOtnoQ0vkpfPrWgqgf0PCMv2dTn/M7A0U2ApI9R3D1XKf4y3a eVRGPANJDLabGxJTwm62XkyAXpa9JZ9FhwXAgiYlUxGj2ivfBfHVcQ7gJj0bMPzKANrhc9 PpPvip4Ksx76TDnAuV33LqMfFnACKrU= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-120-tABAyTPVMAS2rVfRenT5Ag-1; Thu, 22 Feb 2024 11:07:58 -0500 X-MC-Unique: tABAyTPVMAS2rVfRenT5Ag-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BB19E282D3CB; Thu, 22 Feb 2024 16:07:57 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.8]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 55CDBC1596E; Thu, 22 Feb 2024 16:07:57 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 41MG7mDX2174272 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Feb 2024 17:07:48 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 41MG7l9b2174271; Thu, 22 Feb 2024 17:07:47 +0100 Date: Thu, 22 Feb 2024 17:07:47 +0100 From: Jakub Jelinek To: Michael Matz , "Joseph S. Myers" , Richard.Sandiford@arm.com Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c, v2: Handle scoped attributes in __has*attribute and scoped attribute parsing changes in -std=c11 etc. modes [PR114007] Message-ID: References: <42ccc59d-ba79-8680-ec7c-42c9e2bd2a9b@suse.de> <0a760ad0-e90e-243c-cbb5-a5a252f260b2@suse.de> MIME-Version: 1.0 In-Reply-To: <0a760ad0-e90e-243c-cbb5-a5a252f260b2@suse.de> X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org On Thu, Feb 22, 2024 at 04:35:22PM +0100, Michael Matz wrote: > On Thu, 22 Feb 2024, Jakub Jelinek wrote: > > > > Hmm, shouldn't you be able to use (nonexistence of) the PREV_WHITE flag on > > > the second COLON token to see that it's indeed a '::' without intervening > > > whitespace? Instead of setting a new flag on the first COLON token? > > > > > > I.e. something like this: > > > > > > if (c_parser_next_token_is (parser, CPP_SCOPE) > > > - || (loose_scope_p > > > - && c_parser_next_token_is (parser, CPP_COLON) > > > && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) > > > + && !(c_parser_peek_2nd_token (parser)->flags & PREV_WHITE))) > > > > > > ? > > > > That doesn't seem to work. > > Too bad then. I had hoped it would make the code easier without changes > to c-lex. Well, then ... was worth a try, I'll crouch back under my stone > :) Actually, I could make it work with two simple add_flags |= PREV_WHITE; in c_lex_with_flags. PREV_WHITE in FE tokens is only checked in this new spot in [[]] C parsing and in /* If we find the sequence `[:' after a template-name, it's probably a digraph-typo for `< ::'. Substitute the tokens and check if we can parse correctly the argument list. */ if (((next_token = cp_lexer_peek_token (parser->lexer))->type == CPP_OPEN_SQUARE) && next_token->flags & DIGRAPH && ((next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2))->type == CPP_COLON) && !(next_token_2->flags & PREV_WHITE)) { cp_parser_parse_tentatively (parser); /* Change `:' into `::'. */ next_token_2->type = CPP_SCOPE; /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is CPP_LESS. */ cp_lexer_consume_token (parser->lexer); in C++ FE and the same workaround in another spot. But seems -std=c++98 -fpermissive on struct S{}; template struct U{}; U<::S> u; U<:/**/:S> v; #define FOO <: #define BAR U FOO BAR S> w; actually doesn't change, u is accepted with -fpermissive and v/w are rejected without/with the patch, apparently it already has PREV_WHITE flag set in those cases for some reason. 2024-02-22 Jakub Jelinek PR c/114007 gcc/ * doc/extend.texi: (__extension__): Remove comments about scope tokens vs. two colons. gcc/c-family/ * c-lex.cc (c_common_has_attribute): Parse 2 CPP_COLONs with the second one without PREV_WHITE flag the same as CPP_SCOPE. (c_lex_with_flags): For CPP_PADDING or CPP_COMMENT, or PREV_WHITE into add_flags. gcc/c/ * c-parser.cc (c_parser_std_attribute): Remove loose_scope_p argument. Instead of checking it, parse 2 CPP_COLONs with the second one without PREV_WHITE flag the same as CPP_SCOPE. (c_parser_std_attribute_list): Remove loose_scope_p argument, don't pass it to c_parser_std_attribute. (c_parser_std_attribute_specifier): Adjust c_parser_std_attribute_list caller. gcc/testsuite/ * gcc.dg/c23-attr-syntax-6.c: Adjust testcase for :: being valid even in -std=c11 even without __extension__ and : : etc. not being valid anymore even with __extension__. * gcc.dg/c23-attr-syntax-7.c: Likewise. * gcc.dg/c23-attr-syntax-8.c: New test. Jakub --- gcc/doc/extend.texi.jj 2024-02-22 10:10:18.907029080 +0100 +++ gcc/doc/extend.texi 2024-02-22 16:06:33.197555930 +0100 @@ -12626,10 +12626,7 @@ In C, writing: @end smallexample suppresses warnings about using @samp{[[]]} attributes in C versions -that predate C23@. Since the scope token @samp{::} is not a single -lexing token in earlier versions of C, this construct also allows two colons -to be used in place of @code{::}. GCC does not check whether the two -colons are immediately adjacent. +that predate C23@. @end itemize @code{__extension__} has no effect aside from this. --- gcc/c-family/c-lex.cc.jj 2024-02-22 10:09:48.408450163 +0100 +++ gcc/c-family/c-lex.cc 2024-02-22 16:40:59.003000082 +0100 @@ -357,7 +357,27 @@ c_common_has_attribute (cpp_reader *pfil do nxt_token = cpp_peek_token (pfile, idx++); while (nxt_token->type == CPP_PADDING); - if (nxt_token->type == CPP_SCOPE) + if (!c_dialect_cxx () + && flag_iso + && !flag_isoc23 + && nxt_token->type == CPP_COLON) + { + const cpp_token *prev_token = nxt_token; + nxt_token = cpp_peek_token (pfile, idx); + if (nxt_token->type == CPP_COLON + && (nxt_token->flags & PREV_WHITE) == 0) + { + /* __has_attribute (vendor::attr) in -std=c17 etc. modes. + :: isn't CPP_SCOPE but 2 CPP_COLON tokens, where the + second one shouldn't have PREV_WHITE flag to distinguish + it from : :. */ + have_scope = true; + get_token_no_padding (pfile); // Eat first colon. + } + else + nxt_token = prev_token; + } + if (nxt_token->type == CPP_SCOPE || have_scope) { have_scope = true; get_token_no_padding (pfile); // Eat scope. @@ -556,6 +576,7 @@ c_lex_with_flags (tree *value, location_ switch (type) { case CPP_PADDING: + add_flags |= CPP_PADDING; goto retry; case CPP_NAME: @@ -769,6 +790,7 @@ c_lex_with_flags (tree *value, location_ when it is a FALLTHROUGH comment, in that case set PREV_FALLTHROUGH flag on the next non-comment token. */ case CPP_COMMENT: + add_flags |= PREV_WHITE; if (tok->flags & PREV_FALLTHROUGH) { do --- gcc/c/c-parser.cc.jj 2024-02-22 10:09:48.467449349 +0100 +++ gcc/c/c-parser.cc 2024-02-22 16:11:05.320795586 +0100 @@ -5705,8 +5705,7 @@ c_parser_omp_sequence_args (c_parser *pa indicates whether this relaxation is in effect. */ static tree -c_parser_std_attribute (c_parser *parser, bool for_tm, - bool loose_scope_p = false) +c_parser_std_attribute (c_parser *parser, bool for_tm) { c_token *token = c_parser_peek_token (parser); tree ns, name, attribute; @@ -5720,9 +5719,10 @@ c_parser_std_attribute (c_parser *parser name = canonicalize_attr_name (token->value); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_SCOPE) - || (loose_scope_p + || (!flag_isoc23 && c_parser_next_token_is (parser, CPP_COLON) - && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON + && (c_parser_peek_2nd_token (parser)->flags & PREV_WHITE) == 0)) { ns = name; if (c_parser_next_token_is (parser, CPP_COLON)) @@ -5841,8 +5841,7 @@ c_parser_std_attribute (c_parser *parser } static tree -c_parser_std_attribute_list (c_parser *parser, bool for_tm, - bool loose_scope_p = false) +c_parser_std_attribute_list (c_parser *parser, bool for_tm) { tree attributes = NULL_TREE; while (true) @@ -5855,7 +5854,7 @@ c_parser_std_attribute_list (c_parser *p c_parser_consume_token (parser); continue; } - tree attribute = c_parser_std_attribute (parser, for_tm, loose_scope_p); + tree attribute = c_parser_std_attribute (parser, for_tm); if (attribute != error_mark_node) { TREE_CHAIN (attribute) = attributes; @@ -5883,7 +5882,7 @@ c_parser_std_attribute_specifier (c_pars { auto ext = disable_extension_diagnostics (); c_parser_consume_token (parser); - attributes = c_parser_std_attribute_list (parser, for_tm, true); + attributes = c_parser_std_attribute_list (parser, for_tm); restore_extension_diagnostics (ext); } else --- gcc/testsuite/gcc.dg/c23-attr-syntax-6.c.jj 2024-02-22 10:09:48.912443204 +0100 +++ gcc/testsuite/gcc.dg/c23-attr-syntax-6.c 2024-02-22 16:06:33.227555515 +0100 @@ -9,19 +9,14 @@ typedef int [[__extension__ gnu::vector_size (4)]] g1; typedef int [[__extension__ gnu :: vector_size (4)]] g2; -typedef int [[__extension__ gnu : : vector_size (4)]] g3; -typedef int [[__extension__ gnu: :vector_size (4)]] g4; -typedef int [[__extension__ gnu FOO vector_size (4)]] g5; -typedef int [[__extension__ gnu BAR BAR vector_size (4)]] g6; -typedef int [[__extension__ gnu :/**/: vector_size (4)]] g7; -typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] g8; -typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g10; -typedef int [[__extension__]] g11; -typedef int [[__extension__,]] g12; -typedef int [[__extension__, ,,,, ,, ,]] g13; -[[__extension__ deprecated]] int g14 (); -[[__extension__ nodiscard]] int g15 (); -[[__extension__ noreturn]] void g16 (); +typedef int [[__extension__ gnu FOO vector_size (4)]] g3; +typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g4; +typedef int [[__extension__]] g5; +typedef int [[__extension__,]] g6; +typedef int [[__extension__, ,,,, ,, ,]] g7; +[[__extension__ deprecated]] int g8 (); +[[__extension__ nodiscard]] int g9 (); +[[__extension__ noreturn]] void g10 (); int cases (int x) @@ -51,12 +46,42 @@ typedef int [[__extension__ unknown_attr typedef int [[__extension__ gnu:vector_size(4)]] b4; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */ -typedef int [[gnu::vector_size(4)]] b6; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */ +typedef int [[__extension__ gnu : : vector_size (4)]] b6; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu: :vector_size (4)]] b7; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu BAR BAR vector_size (4)]] b8; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu :/**/: vector_size (4)]] b9; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] b10; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[gnu::vector_size(4)]] b11; /* { dg-error {attributes before C23} } */ +typedef int [[gnu : : vector_size(4)]] b12; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu : vector_size(4)]] b13; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu: :vector_size (4)]] b14; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu BAR BAR vector_size (4)]] b15; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ /* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ -typedef int [[gnu : : vector_size(4)]] b7; /* { dg-error {expected '\]' before ':'} } */ +typedef int [[gnu :/**/: vector_size (4)]] b16; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ /* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ -typedef int [[gnu : vector_size(4)]] b8; /* { dg-error {expected '\]' before ':'} } */ +typedef int [[gnu JOIN(:,:) vector_size (4)]] b17; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ /* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu :: vector_size (4)]] b18; /* { dg-error {attributes before C23} } */ +typedef int [[gnu FOO vector_size (4)]] b19; /* { dg-error {attributes before C23} } */ +typedef int [[gnu :: vector_size (sizeof (void (*)(...)))]] b20; /* { dg-error {attributes before C23} } */ +/* { dg-error {requires a named argument before} "" { target *-*-* } .-1 } */ +typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */ +/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */ +/* { dg-error {attributes before C23} "" { target *-*-* } .-3 } */ --- gcc/testsuite/gcc.dg/c23-attr-syntax-7.c.jj 2024-02-22 10:09:48.957442583 +0100 +++ gcc/testsuite/gcc.dg/c23-attr-syntax-7.c 2024-02-22 16:06:33.227555515 +0100 @@ -9,19 +9,14 @@ typedef int [[__extension__ gnu::vector_size (4)]] g1; typedef int [[__extension__ gnu :: vector_size (4)]] g2; -typedef int [[__extension__ gnu : : vector_size (4)]] g3; -typedef int [[__extension__ gnu: :vector_size (4)]] g4; -typedef int [[__extension__ gnu FOO vector_size (4)]] g5; -typedef int [[__extension__ gnu BAR BAR vector_size (4)]] g6; -typedef int [[__extension__ gnu :/**/: vector_size (4)]] g7; -typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] g8; -typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g10; -typedef int [[__extension__]] g11; -typedef int [[__extension__,]] g12; -typedef int [[__extension__, ,,,, ,, ,]] g13; -[[__extension__ deprecated]] int g14 (); -[[__extension__ nodiscard]] int g15 (); -[[__extension__ noreturn]] void g16 (); +typedef int [[__extension__ gnu FOO vector_size (4)]] g3; +typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g4; +typedef int [[__extension__]] g5; +typedef int [[__extension__,]] g6; +typedef int [[__extension__, ,,,, ,, ,]] g7; +[[__extension__ deprecated]] int g8 (); +[[__extension__ nodiscard]] int g9 (); +[[__extension__ noreturn]] void g10 (); int cases (int x) @@ -51,10 +46,37 @@ typedef int [[__extension__ unknown_attr typedef int [[__extension__ gnu:vector_size(4)]] b4; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5; -typedef int [[gnu::vector_size(4)]] b6; /* { dg-warning {attributes before C23} } */ -typedef int [[gnu : : vector_size(4)]] b7; /* { dg-error {expected '\]' before ':'} } */ +typedef int [[__extension__ gnu : : vector_size (4)]] b6; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu: :vector_size (4)]] b7; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu BAR BAR vector_size (4)]] b8; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu :/**/: vector_size (4)]] b9; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] b10; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +typedef int [[gnu::vector_size(4)]] b11; /* { dg-warning {attributes before C23} } */ +typedef int [[gnu : : vector_size(4)]] b12; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu : vector_size(4)]] b13; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu: :vector_size (4)]] b14; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu BAR BAR vector_size (4)]] b15; /* { dg-error {expected '\]' before ':'} } */ +/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ +/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu :/**/: vector_size (4)]] b16; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ /* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ -typedef int [[gnu : vector_size(4)]] b8; /* { dg-error {expected '\]' before ':'} } */ +typedef int [[gnu JOIN(:,:) vector_size (4)]] b17; /* { dg-error {expected '\]' before ':'} } */ /* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */ /* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */ +typedef int [[gnu :: vector_size (4)]] b18; /* { dg-warning {attributes before C23} } */ +typedef int [[gnu FOO vector_size (4)]] b19; /* { dg-warning {attributes before C23} } */ +typedef int [[gnu :: vector_size (sizeof (void (*)(...)))]] b20; /* { dg-warning {attributes before C23} } */ +/* { dg-warning {requires a named argument before} "" { target *-*-* } .-1 } */ +typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-warning {attributes before C23} } */ --- gcc/testsuite/gcc.dg/c23-attr-syntax-8.c.jj 2024-02-22 16:06:33.227555515 +0100 +++ gcc/testsuite/gcc.dg/c23-attr-syntax-8.c 2024-02-22 16:06:33.227555515 +0100 @@ -0,0 +1,12 @@ +/* PR c/114007 */ +/* { dg-do compile } */ +/* { dg-options "-std=c11" } */ + +#if __has_c_attribute (gnu::unused) +[[gnu::unused]] +#endif +int i; +#if __has_cpp_attribute (gnu::unused) +[[gnu::unused]] +#endif +int j;