From patchwork Tue Dec 5 16:03:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 174106 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp3537738vqy; Tue, 5 Dec 2023 08:12:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IGu2VYPCANTdytumaS6HKA6+0RAelMiHCrQsyrT+ExI+l0b8zfyeA7w0YNXXx8qAPQn2Z8G X-Received: by 2002:a05:620a:2a03:b0:77e:fba4:3a2a with SMTP id o3-20020a05620a2a0300b0077efba43a2amr1687352qkp.128.1701792724893; Tue, 05 Dec 2023 08:12:04 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1701792724; cv=pass; d=google.com; s=arc-20160816; b=oy7QsTLGdZ0IAoK90voYGrLxLcq3LqFEfThgds5xNxdReOwrxmd5IxeWeU24arYDwh Oj2ykO+QQgatWcYvh08aXHnddUzZizXGmEPbc/TLve9hSlNrqPHVM5ubT1D0YmLBRyny DpT5OdyGJJUEY2Nl8Ns0poDfQypn2xPx94r6MLqxGmjyMy3h5p0vJJp/lshkZvfeNZxS DnD5elgDxxdjSly38rhWNLkf+Egmt5I4uIVvh2IonqZRC5XXZ8pCz03NNY8PkbRNbAst mFO7813n4fhsYGu73UVm4eu1nfLTck9AS+LFllNlPNcjq9NDFXJjMZAjCrqIwWao6K+i Ifag== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:reply-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-disposition:in-reply-to :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=r04StePwkCR5plbqtiKsSlpSEE3jtZS3Egid/326TC4=; fh=0xZT+NBKSeH8qOu04/61f1ZGePpF4jF/gxp331YE14k=; b=ufYAqQrvJvCgC0hcTpHP9jincULNF8VQfeATbjskMO0X80jgdp0eJVNHw9KiYMm3Qa jlVIKz8+itM3dtYGzSkiqd8Vl3LWouM93GthAEgjhDcFO8YcaPLHa++cK1sqmx2pNSaJ Lfyoz2OsagyD4qEpWUDTXiPPeJ8E5hvrgsjuWvccc8lVu+MNLppMeQEe3FNoswCPEFr0 UT276FpTeEGO7uaisHw4a0ncciaoll7WJqclgtTvGmd8YWdhyrnIQSSxAa6vSqM7j4OU G7v2AcGbi0emeB1NQaBuYhnO7tOqEMclTG0EFVvqNxzMkkmqW1YHanEprQJ21x3Ww3LA /ZXQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NfVF6WI6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id m1-20020a05620a290100b0077d69eda134si12751574qkp.306.2023.12.05.08.12.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 08:12:04 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NfVF6WI6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A4982386583C for ; Tue, 5 Dec 2023 16:12:04 +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 ED1B83845BDC for ; Tue, 5 Dec 2023 16:11:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ED1B83845BDC 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 ED1B83845BDC 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=1701792700; cv=none; b=YxRXRiNVnEFeAjmVosfn+Sap01GFDbQ+P7zbgSQITSwuciAu8GXddPOx9O2YLXRq/9lUSUIcTNFVu20FiexajUWscUAio27zRtN/X3vx4dfKL+C9Zq2WMwgKwLNDvc2LO84+aBRY4G3nvtK2AVoeFxggjFG1WaCMVpwit+kXCdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701792700; c=relaxed/simple; bh=c8uXaM+ha7dTTbh2PPFOr5GzG4XAkFEdS2j5WdvX1Qo=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=k0yPxPo2n1lbeuWuM2mGogSN8tTBr9nFyX1I32dnPQBIyG5x651WZCS3VzdMxFpsR2Ja9L9oAKXxd6hD29h0yfZGRk4M9/J6E52vUMODKsQH3nnofCz0NEqyGnfxAKqzwUqnGSCPJ7f7A8jktWOUruw7j6PDS5eKn9OvnfWDFHA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701792690; 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=r04StePwkCR5plbqtiKsSlpSEE3jtZS3Egid/326TC4=; b=NfVF6WI6/jxzvsPsN1rILo5AvbDBX80YECKP8+Y4oWdBDfczH+ePMw7W3DJBg2H7iGF9Jb Na3VAd4zLNFQkruAU4nffHxN2Msw9qvRH5YDEinLhqLBHQuAZp0ADI+qG9k7b3y9o2+p5z i2Eo23C/ejQ8kZc3sCZ/3RPcCvQ+Lr8= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-542-ThkHIco9MH20Voo6aKnxqQ-1; Tue, 05 Dec 2023 11:11:07 -0500 X-MC-Unique: ThkHIco9MH20Voo6aKnxqQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (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 BAF0D833A33 for ; Tue, 5 Dec 2023 16:03:17 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.195.157]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 62D782166B31; Tue, 5 Dec 2023 16:03:17 +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 3B5G3Fto1974812 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 5 Dec 2023 17:03:15 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 3B5G3EF21974309; Tue, 5 Dec 2023 17:03:14 +0100 Date: Tue, 5 Dec 2023 17:03:14 +0100 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++, v2: Further #pragma GCC unroll C++ fix [PR112795] Message-ID: References: <984d11ad-ba57-4a7a-aa50-61296162c325@redhat.com> MIME-Version: 1.0 In-Reply-To: <984d11ad-ba57-4a7a-aa50-61296162c325@redhat.com> X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.4 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_H3, 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+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784459007924646643 X-GMAIL-MSGID: 1784459007924646643 On Tue, Dec 05, 2023 at 10:07:19AM -0500, Jason Merrill wrote: > Please. Maybe check_pragma_unroll? check_unroll_factor? So like this (assuming it passes bootstrap/regtest, so far passed just GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ RUNTESTFLAGS="dg.exp='unroll*'" )? 2023-12-05 Jakub Jelinek PR c++/112795 * cp-tree.h (cp_check_pragma_unroll): Declare. * semantics.cc (cp_check_pragma_unroll): New function. * parser.cc (cp_parser_pragma_unroll): Use cp_check_pragma_unroll. * pt.cc (tsubst_expr) : Likewise. (tsubst_stmt) : Likwsie. * g++.dg/ext/unroll-2.C: Use { target c++11 } instead of dg-skip-if for -std=gnu++98. * g++.dg/ext/unroll-3.C: Likewise. * g++.dg/ext/unroll-7.C: New test. * g++.dg/ext/unroll-8.C: New test. Jakub --- gcc/cp/cp-tree.h.jj 2023-12-05 09:06:06.140878013 +0100 +++ gcc/cp/cp-tree.h 2023-12-05 16:21:05.564736203 +0100 @@ -7918,6 +7918,7 @@ extern tree most_general_lambda (tree) extern tree finish_omp_target (location_t, tree, tree, bool); extern void finish_omp_target_clauses (location_t, tree, tree *); extern void maybe_warn_unparenthesized_assignment (tree, tsubst_flags_t); +extern tree cp_check_pragma_unroll (location_t, tree); /* in tree.cc */ extern int cp_tree_operand_length (const_tree); --- gcc/cp/semantics.cc.jj 2023-12-04 08:59:06.888357091 +0100 +++ gcc/cp/semantics.cc 2023-12-05 16:56:03.718410332 +0100 @@ -13016,4 +13016,33 @@ cp_build_bit_cast (location_t loc, tree return ret; } +/* Diagnose invalid #pragma GCC unroll argument and adjust + it if needed. */ + +tree +cp_check_pragma_unroll (location_t loc, tree unroll) +{ + HOST_WIDE_INT lunroll = 0; + if (type_dependent_expression_p (unroll)) + ; + else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll)) + || (!value_dependent_expression_p (unroll) + && (!tree_fits_shwi_p (unroll) + || (lunroll = tree_to_shwi (unroll)) < 0 + || lunroll >= USHRT_MAX))) + { + error_at (loc, "%<#pragma GCC unroll%> requires an" + " assignment-expression that evaluates to a non-negative" + " integral constant less than %u", USHRT_MAX); + unroll = integer_one_node; + } + else if (TREE_CODE (unroll) == INTEGER_CST) + { + unroll = fold_convert (integer_type_node, unroll); + if (integer_zerop (unroll)) + unroll = integer_one_node; + } + return unroll; +} + #include "gt-cp-semantics.h" --- gcc/cp/parser.cc.jj 2023-12-05 09:05:37.533281014 +0100 +++ gcc/cp/parser.cc 2023-12-05 16:18:32.224909370 +0100 @@ -50243,27 +50243,7 @@ cp_parser_pragma_unroll (cp_parser *pars { location_t location = cp_lexer_peek_token (parser->lexer)->location; tree unroll = cp_parser_constant_expression (parser); - unroll = fold_non_dependent_expr (unroll); - HOST_WIDE_INT lunroll = 0; - if (type_dependent_expression_p (unroll)) - ; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll)) - || (!value_dependent_expression_p (unroll) - && (!tree_fits_shwi_p (unroll) - || (lunroll = tree_to_shwi (unroll)) < 0 - || lunroll >= USHRT_MAX))) - { - error_at (location, "%<#pragma GCC unroll%> requires an" - " assignment-expression that evaluates to a non-negative" - " integral constant less than %u", USHRT_MAX); - unroll = NULL_TREE; - } - else if (TREE_CODE (unroll) == INTEGER_CST) - { - unroll = fold_convert (integer_type_node, unroll); - if (integer_zerop (unroll)) - unroll = integer_one_node; - } + unroll = cp_check_pragma_unroll (location, fold_non_dependent_expr (unroll)); cp_parser_skip_to_pragma_eol (parser, pragma_tok); return unroll; } --- gcc/cp/pt.cc.jj 2023-12-05 09:06:06.175877520 +0100 +++ gcc/cp/pt.cc 2023-12-05 16:48:05.641109116 +0100 @@ -18407,22 +18407,24 @@ tsubst_stmt (tree t, tree args, tsubst_f complain, in_decl, decomp); } + tree unroll = RECUR (RANGE_FOR_UNROLL (t)); + if (unroll) + unroll + = cp_check_pragma_unroll (EXPR_LOCATION (RANGE_FOR_UNROLL (t)), + unroll); if (processing_template_decl) { RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t); - RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t); + RANGE_FOR_UNROLL (stmt) = unroll; RANGE_FOR_NOVECTOR (stmt) = RANGE_FOR_NOVECTOR (t); finish_range_for_decl (stmt, decl, expr); if (decomp && decl != error_mark_node) cp_finish_decomp (decl, decomp); } else - { - tree unroll = RECUR (RANGE_FOR_UNROLL (t)); - stmt = cp_convert_range_for (stmt, decl, expr, decomp, - RANGE_FOR_IVDEP (t), unroll, - RANGE_FOR_NOVECTOR (t)); - } + stmt = cp_convert_range_for (stmt, decl, expr, decomp, + RANGE_FOR_IVDEP (t), unroll, + RANGE_FOR_NOVECTOR (t)); bool prev = note_iteration_stmt_body_start (); RECUR (RANGE_FOR_BODY (t)); @@ -21506,30 +21508,8 @@ tsubst_expr (tree t, tree args, tsubst_f tree op3 = RECUR (TREE_OPERAND (t, 2)); if (TREE_CODE (op2) == INTEGER_CST && wi::to_widest (op2) == (int) annot_expr_unroll_kind) - { - HOST_WIDE_INT lunroll; - if (type_dependent_expression_p (op3)) - ; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (op3)) - || (!value_dependent_expression_p (op3) - && (!tree_fits_shwi_p (op3) - || (lunroll = tree_to_shwi (op3)) < 0 - || lunroll >= USHRT_MAX))) - { - error_at (EXPR_LOCATION (TREE_OPERAND (t, 2)), - "%<#pragma GCC unroll%> requires an " - "assignment-expression that evaluates to a " - "non-negative integral constant less than %u", - USHRT_MAX); - op3 = integer_one_node; - } - else if (TREE_CODE (op3) == INTEGER_CST) - { - op3 = fold_convert (integer_type_node, op3); - if (integer_zerop (op3)) - op3 = integer_one_node; - } - } + op3 = cp_check_pragma_unroll (EXPR_LOCATION (TREE_OPERAND (t, 2)), + op3); RETURN (build3_loc (EXPR_LOCATION (t), ANNOTATE_EXPR, TREE_TYPE (op1), op1, op2, op3)); } --- gcc/testsuite/g++.dg/ext/unroll-2.C.jj 2023-12-04 11:55:52.154142189 +0100 +++ gcc/testsuite/g++.dg/ext/unroll-2.C 2023-12-05 16:17:29.976792279 +0100 @@ -1,6 +1,5 @@ -// { dg-do compile } +// { dg-do compile { target c++11 } } // { dg-options "-O2 -fdump-tree-cunrolli-details" } -// { dg-skip-if "range for" { *-*-* } { "-std=gnu++98" } { "" } } void foo (int (&a)[8], int *b, int *c) --- gcc/testsuite/g++.dg/ext/unroll-3.C.jj 2023-12-04 11:55:52.154142189 +0100 +++ gcc/testsuite/g++.dg/ext/unroll-3.C 2023-12-05 16:17:29.988792108 +0100 @@ -1,6 +1,5 @@ -// { dg-do compile } +// { dg-do compile { target c++11 } } // { dg-options "-O2 -fdump-tree-cunrolli-details" } -// { dg-skip-if "range for" { *-*-* } { "-std=gnu++98" } { "" } } template void --- gcc/testsuite/g++.dg/ext/unroll-7.C.jj 2023-12-05 16:17:29.988792108 +0100 +++ gcc/testsuite/g++.dg/ext/unroll-7.C 2023-12-05 16:17:29.988792108 +0100 @@ -0,0 +1,45 @@ +// PR c++/112795 +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -fdump-tree-cunrolli-details" } + +void baz (int); +constexpr int n = 3; +constexpr int m = 7; + +template +void +foo (int (&a)[3], T b) +{ +#pragma GCC unroll(n) + for (auto i : a) + baz (i); +#pragma GCC unroll(m) + for (auto i : b) + baz (i); +} + +template +void +bar (int (&a)[N]) +{ +#pragma GCC unroll(N) + for (auto i : a) + baz (i); +} + +void +qux () +{ + int a[3] = { 1, 2, 3 }; + int b[7] = { 4, 5, 6, 7, 8, 9, 10 }; + int c[6] = { 11, 12, 13, 14, 15, 16 }; + int d[10] = { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; + foo (a, b); + bar <6> (c); + bar <10> (d); +} + +// { dg-final { scan-tree-dump "loop with 3 iterations completely unrolled" "cunrolli" } } +// { dg-final { scan-tree-dump "loop with 6 iterations completely unrolled" "cunrolli" } } +// { dg-final { scan-tree-dump "loop with 7 iterations completely unrolled" "cunrolli" } } +// { dg-final { scan-tree-dump "loop with 10 iterations completely unrolled" "cunrolli" } } --- gcc/testsuite/g++.dg/ext/unroll-8.C.jj 2023-12-05 16:17:29.988792108 +0100 +++ gcc/testsuite/g++.dg/ext/unroll-8.C 2023-12-05 16:17:29.988792108 +0100 @@ -0,0 +1,86 @@ +// PR c++/112795 +// { dg-do compile { target c++11 } } + +void +foo (int (&a)[3]) +{ + #pragma GCC unroll 1.0f // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll 0xffffffffffffffffULL // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll -42 // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; +} + +template +void +bar (U a) +{ + #pragma GCC unroll 1.0f // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll 0xffffffffffffffffULL // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll -42 // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; +} + +template +void +baz (U a) +{ + #pragma GCC unroll (N + 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll (N + 0xffffffffffffffffULL) + for (auto i : a) + ; + #pragma GCC unroll (N - 42) + for (auto i : a) + ; + #pragma GCC unroll ((T) 1.0f) + for (auto i : a) + ; + #pragma GCC unroll ((T) 0xffffffffffffffffULL) + for (auto i : a) + ; + #pragma GCC unroll ((T) -42) + for (auto i : a) + ; +} + +template +void +qux (U a) +{ + #pragma GCC unroll (N + 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll (N + 0xffffffffffffffffULL)// { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll (N - 42) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll ((T) 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll ((T) 0xffffffffffffffffULL)// { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; + #pragma GCC unroll ((T) -42) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } + for (auto i : a) + ; +} + +void +corge () +{ + int a[3] = { 1, 2, 3 }; + qux (a); +}