From patchwork Wed Feb 17 01:04:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 583798 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2FC891402AC for ; Wed, 17 Feb 2016 12:05:09 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=FlfjcB3r; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=OO2IZUFog+DSLaa0v R6HDPkhw7YlGKM1L8WwdS0tN0SP8LzU/S1oRiSqr9YEWcc9t3E67Pf3A6BQFSThc FtPNjQ5c34EbIF0eXT2rwly6K5oYcjtoRicbjJyRbmlqPaft40+UWi5SyXWIXG3h /dUoDIqbB+W/MioNDdD7NTdXs0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=F1qBKre+7yW44TRngTIQ6oy 2Ufs=; b=FlfjcB3rwRvZ18CbunAOmOBJPJv9E4jxn8Zbz1lENYSKnrZrt5FdyHv sspuqBkH4lQR8QrszZKU9ptlWAB8JN0Fd4PuK9Z59VsqXbhZGTE90fERC2UhBb1p 1ZWqFXihJ0gckphlNFKFWUEnjThHhKgSRU2RyhyGncz7C9vhbPmA= Received: (qmail 4609 invoked by alias); 17 Feb 2016 01:05:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4592 invoked by uid 89); 17 Feb 2016 01:04:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=discretion, 1101, msebor@redhat.com, mseborredhatcom X-HELO: mail-qg0-f47.google.com Received: from mail-qg0-f47.google.com (HELO mail-qg0-f47.google.com) (209.85.192.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 17 Feb 2016 01:04:55 +0000 Received: by mail-qg0-f47.google.com with SMTP id y9so1235665qgd.3 for ; Tue, 16 Feb 2016 17:04:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type; bh=mdSyknTWF+5tcSWgbAldvGZlCgjKj3z1W4p7+vm9+aU=; b=RtAqNuA/1QrAuHxZy25OemciE8GTQ+yD9Z/V8eaXOjkzeonpqfxQ4A9jsMH1n3GpwD 6bQO/DZAs2ALxA3ATD0l2sJXbKBoppUN4o5KQd2JSuZgHh3Lo+UnLbTn2t24U5TCeqUK tPhYnDr/r6cCKBX12YQpo+nr1CWM5Qz6kKgR93p+n7s9VVmlQIMTIANptloykOTDa1EN Nzz8ssk3v1l0kUJoTnyYzGXdDGEmQawmrVei1MLGy73JPHqlEP6Yd+vhRWp7BKuGP3Ds 8UHfrl63C5cQman0UJVZkTXjHU4G0XaYUrrDa8qaYwrWcdQjZdv7OCqX2OOUcZp408td 0vvA== X-Gm-Message-State: AG10YOT5TRtFZw0hVEHw6LQsYPsfK4zpFXWXWbsjm5V3sUo2ZRSwxuCwJXMwHEKvQxOxtw== X-Received: by 10.140.145.72 with SMTP id 69mr32917365qhr.95.1455671092163; Tue, 16 Feb 2016 17:04:52 -0800 (PST) Received: from [192.168.0.26] (71-215-88-205.hlrn.qwest.net. [71.215.88.205]) by smtp.gmail.com with ESMTPSA id v70sm13482228qge.25.2016.02.16.17.04.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Feb 2016 17:04:51 -0800 (PST) Subject: Re: [PATCH] 69780 - [4.9/5/6 Regression] ICE on __builtin_alloca_with_align, with small alignment To: Jakub Jelinek References: <56C134ED.9060106@gmail.com> <20160215082933.GW3017@tucnak.redhat.com> Cc: Gcc Patch List From: Martin Sebor Message-ID: <56C3C730.1060602@gmail.com> Date: Tue, 16 Feb 2016 18:04:48 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 In-Reply-To: <20160215082933.GW3017@tucnak.redhat.com> X-IsSubscribed: yes On 02/15/2016 01:29 AM, Jakub Jelinek wrote: > On Sun, Feb 14, 2016 at 07:16:13PM -0700, Martin Sebor wrote: >> + case BUILT_IN_ALLOCA_WITH_ALIGN: >> + { >> + /* Get the requested alignment (in bits) if it's a constant >> + integer expression. */ >> + HOST_WIDE_INT align = >> + TREE_CODE (args [1]) == INTEGER_CST ? tree_to_uhwi (args [1]) : 0; > Thank you for your comments. Attached is an updated patch that corrects most of the problems you pointed out. Also included in this patch is the update to the manual documenting both this intrinsic and __builtin_alloca. I originally submitted that part for review separately but since they are closely related I think they are best reviewed and ultimately committed together. (In the spirit of full disclosure, the review of the documentation change got side-tracked by a discussion of an unrelated topic and would need to be restarted anyway.) > Formatting. = needs to be on the next line. There are literally dozens of examples of this style in this file alone. In one of the two instances of this style in this patch, moving the equals sign to the next line would force me to split the initializer expression over the next two lines to avoid exceeding the 80 character per line limit and make the code harder to read. I also don't see the style you suggest mentioned in the GNU coding standard or in the GCC coding conventions. I would prefer to leave this detail to the discretion of the author. Martin PR middle-end/69780 - [4.9/5/6 Regression] ICE on __builtin_alloca_with_align with small alignment PR c/69759 - __builtin_alloca and __builtin_alloca_with_align undocumented gcc/c-family/ChangeLog: 2016-02-16 Martin Sebor PR middle-end/69780 * c-common.c (check_builtin_function_arguments): Validate and reject invalid arguments to __builtin_alloca_with_align. gcc/ChangeLog: 2016-02-16 Martin Sebor PR c/69759 * doc/extend.texi (Other Builtins): Document __builtin_alloca and __builtin_alloca_with_align. gcc/testsuite/ChangeLog: 2016-02-16 Martin Sebor PR middle-end/69780 * g++.dg/ext/builtin_alloca.C: New test. * gcc.dg/builtins-68.c: New test. Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 233476) +++ gcc/c-family/c-common.c (working copy) @@ -9816,8 +9816,41 @@ check_builtin_function_arguments (tree f || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) return true; +#undef MAX_STACK_ALIGNMENT +#define MAX_STACK_ALIGNMENT __UINT32_MAX__ + switch (DECL_FUNCTION_CODE (fndecl)) { + case BUILT_IN_ALLOCA_WITH_ALIGN: + { + /* Get the requested alignment (in bits) if it's a constant + integer expression. */ + unsigned HOST_WIDE_INT align = + TREE_CODE (args[1]) == INTEGER_CST ? tree_to_uhwi (args[1]) : 0; + + /* Determine if the requested alignment is a power of 2 greater + than CHAR_BIT. */ + if ((align & (align - 1)) == 0) + align >>= LOG2_BITS_PER_UNIT; + else + align = 0; + + /* Reject invalid alignments. */ + if (align < 1 || MAX_STACK_ALIGNMENT < align) + { + /* Compute the maximum stack alignment in bits. */ + unsigned HOST_WIDE_INT max_align_bits = + (unsigned HOST_WIDE_INT)MAX_STACK_ALIGNMENT << LOG2_BITS_PER_UNIT; + + error_at (EXPR_LOC_OR_LOC (args[1], input_location), + "second argument to function %qE must be a constant " + "integer power of 2 between %qi and %qwu", + fndecl, BITS_PER_UNIT, max_align_bits); + return false; + } + return true; + } + case BUILT_IN_CONSTANT_P: return builtin_function_validate_nargs (fndecl, nargs, 1); Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 233476) +++ gcc/doc/extend.texi (working copy) @@ -10144,6 +10144,8 @@ in the Cilk Plus language manual which c @node Other Builtins @section Other Built-in Functions Provided by GCC @cindex built-in functions +@findex __builtin_alloca +@findex __builtin_alloca_with_align @findex __builtin_call_with_static_chain @findex __builtin_fpclassify @findex __builtin_isfinite @@ -10690,6 +10692,89 @@ In the same fashion, GCC provides @code{ @code{__builtin_} prefixed. The @code{isinf} and @code{isnan} built-in functions appear both with and without the @code{__builtin_} prefix. +@deftypefn {Built-in Function} void* __builtin_alloca (size_t size) +The @code{__builtin_alloca} function must be called at block scope. +The function allocates an object @var{size} bytes large on the stack +of the calling function. The object is aligned at the default stack +alignment boundary for the target determined by the +@code{__BIGGEST_ALIGNMENT__} macro. @code{__builtin_alloca} returns +a pointer to the first byte of the allocated object. The lifetime of +the allocated object ends just before the calling function returns to +its caller. This is so even when @code{__builtin_alloca_with_align} +is called within a nested block. + +For example, the following function allocates eight objects of @code{n} +bytes each on the stack, storing a pointer to each in consecutive elements +of the array @code{a}. It then passes the array to function @code{g()} +which can safely use the storage pointed to by each of the array elements. + +@smallexample +void f (unsigned n) +@{ + void *a [8]; + for (int i = 0; i != 8; ++i) + a [i] = __builtin_alloca (n); + + g (a, n); // safe +@} +@end smallexample + +Since the @code{__builtin_alloca} function doesn't validate its arguments +it is the responsibility of its caller to make sure the argument doesn't +cause it doesn't exceed the stack size limit. +The @code{__builtin_alloca} function is provided to make it possible to +allocate arrays with a runtime bound on the stack. Since C99 variable +length arrays offer similar functionality under a portable, more convenient, +and safer interface they are recommended instead, in both C99 and C++ +programs where GCC provides them as an extension. + +@end deftypefn + +@deftypefn {Built-in Function} void* __builtin_alloca_with_align (size_t size, size_t align) +The @code{__builtin_alloca_with_align} function must be called at block +scope. The function allocates an object @var{align} bytes large on +the stack of the calling function. The allocated object is aligned on +the boundary specified by the argument @var{align} whose unit is given +in bits (not bytes). @var{size} must be positive and not exceed the stack +size limit. @var{align} must be a constant integer expression that +evaluates to a power of 2 greater than or equal to @code{__CHAR_BIT__}. +Invocations with other values are rejected with an error. The function +returns a pointer to the first byte of the allocated object. The lifetime +of the allocated object ends at the end of the block in which the function +was called. The allocated storage is released no later than just before +the calling function returns to its called, but may be released at the end +of the block in which the function was called. + +For example, in the following function the call to @code{g()} is unsafe +because when @code{overalign} is non-zero, the space allocated by +@code{__builtin_alloca_with_align} may have been released at the end +of the @code{if} statement in which it was called. + +@smallexample +void f (unsigned n, bool overalign) +@{ + void *p; + if (overalign) + p = __builtin_alloca_with_align (n, 64); + else + p = __builtin_alloc (n); + + g (p, n); // unsafe +@} +@end smallexample + +Since the @code{__builtin_alloca_with_align} function doesn't validate its +arguments it is the responsibility of its caller to make sure the argument +doesn't cause it to exceed the stack size limit. +The @code{__builtin_alloca_with_align} function is provided to make +it possible to allocate overaligned arrays with a runtime bound on +the stack. Since C99 variable length arrays offer the same functionality +under a portable, more convenient, and safer interface they are recommended +instead, in both C99 and C++ programs where GCC provides them as +an extension. + +@end deftypefn + @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2}) You can use the built-in function @code{__builtin_types_compatible_p} to Index: gcc/testsuite/gcc.dg/builtins-68.c =================================================================== --- gcc/testsuite/gcc.dg/builtins-68.c (revision 0) +++ gcc/testsuite/gcc.dg/builtins-68.c (working copy) @@ -0,0 +1,101 @@ +/* PR middle-end/69780 - [4.9/5/6 Regression] ICE on + __builtin_alloca_with_align with small alignment */ +/* { dg-require-effective-target alloca } */ +/* { dg-do compile } */ + +#define CHAR_BIT __CHAR_BIT__ +#define INT_MAX __INT_MAX__ +#define INT_MIN (-INT_MAX - 1) + +static void* p; + +/* Verify that valid __builtin_alloca_with_align expressions are accepted. */ +void test_valid (int n) +{ + enum { + A1 = CHAR_BIT * 1, + A2 = CHAR_BIT * 2, + A4 = CHAR_BIT * 4, + A8 = CHAR_BIT * 8, + A16 = CHAR_BIT * 16, + A32 = CHAR_BIT * 32 + }; + + /* Valid alignments are power of 2 positive multiples of CHAR_BIT. */ + p = __builtin_alloca_with_align (n, CHAR_BIT * 1); + p = __builtin_alloca_with_align (n, CHAR_BIT * 2); + p = __builtin_alloca_with_align (n, CHAR_BIT * 4); + p = __builtin_alloca_with_align (n, CHAR_BIT * 8); + p = __builtin_alloca_with_align (n, CHAR_BIT * 16); + p = __builtin_alloca_with_align (n, CHAR_BIT * 32); + + p = __builtin_alloca_with_align (n, A1); + p = __builtin_alloca_with_align (n, A2); + p = __builtin_alloca_with_align (n, A4); + p = __builtin_alloca_with_align (n, A8); + p = __builtin_alloca_with_align (n, A16); + p = __builtin_alloca_with_align (n, A32); +} + +/* Non-integer alignments must be rejected. */ +void test_arg2_non_int (int n) +{ + /* Verify the full text of the diagnostic just once. */ + p = __builtin_alloca_with_align (n, 0.0); /* { dg-error "second argument to function .__builtin_alloca_with_align. must be a constant integer power of 2 between .8. and " } */ + + /* Disable diagnostic complaining about converting void* to int that + preempts the "constant integer expression" error. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wint-conversion" + + p = __builtin_alloca_with_align (n, (void*)0); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, ""); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, L""); /* { dg-error "must be a constant integer" } */ + +#pragma GCC diagnostic pop + +} + +/* Integer alignment that's not a constant expression must be rejected. */ +void test_arg2_non_const (int n, int a1) +{ + extern const int a2; + static const int a3 = CHAR_BIT; + static volatile const int a4 = CHAR_BIT; + + p = __builtin_alloca_with_align (n, a1); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, a2); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, a3); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, a4); /* { dg-error "must be a constant integer" } */ +} + +/* Constant integer alignment that's not a power of 2 positive multiple + of CHAR_BIT must be rejected. */ +void test_arg2_non_pow2 (int n) +{ + p = __builtin_alloca_with_align (n, INT_MIN); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, -1); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, !1); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, !0); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 0); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 1); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 2); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 3); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 4); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 5); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 6); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 7); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 9); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 10); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 11); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 12); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 13); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 14); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 15); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 17); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 31); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 33); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 63); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, 65); /* { dg-error "must be a constant integer" } */ + p = __builtin_alloca_with_align (n, INT_MAX); /* { dg-error "must be a constant integer" } */ +} Index: gcc/testsuite/g++.dg/ext/builtin_alloca.C =================================================================== --- gcc/testsuite/g++.dg/ext/builtin_alloca.C (revision 0) +++ gcc/testsuite/g++.dg/ext/builtin_alloca.C (working copy) @@ -0,0 +1,183 @@ +// PR middle-end/69780 - [4.9/5/6 Regression] ICE on +// __builtin_alloca_with_align with small alignment +// { dg-require-effective-target alloca } +// { dg-do compile } + +#define CHAR_BIT __CHAR_BIT__ +#define INT_MAX __INT_MAX__ +#define INT_MIN (-INT_MAX - 1) + +static void* p; + +// Verify that valid __builtin_alloca_with_align expressions are accepted. +void test_valid (int n) +{ + enum { + A1 = CHAR_BIT * 1, + A2 = CHAR_BIT * 2, + A4 = CHAR_BIT * 4, + A8 = CHAR_BIT * 8, + A16 = CHAR_BIT * 16, + A32 = CHAR_BIT * 32 + }; + + const int a1 = A1; + const int a2 = A2; + const int a4 = A4; + const int a8 = A8; + const int a16 = A16; + const int a32 = A32; + + // Valid alignments are power of 2 positive multiples of CHAR_BIT. + p = __builtin_alloca_with_align (n, CHAR_BIT * 1); + p = __builtin_alloca_with_align (n, CHAR_BIT * 2); + p = __builtin_alloca_with_align (n, CHAR_BIT * 4); + p = __builtin_alloca_with_align (n, CHAR_BIT * 8); + p = __builtin_alloca_with_align (n, CHAR_BIT * 16); + p = __builtin_alloca_with_align (n, CHAR_BIT * 32); + + p = __builtin_alloca_with_align (n, A1); + p = __builtin_alloca_with_align (n, A2); + p = __builtin_alloca_with_align (n, A4); + p = __builtin_alloca_with_align (n, A8); + p = __builtin_alloca_with_align (n, A16); + p = __builtin_alloca_with_align (n, A32); + + p = __builtin_alloca_with_align (n, a1); + p = __builtin_alloca_with_align (n, a2); + p = __builtin_alloca_with_align (n, a4); + p = __builtin_alloca_with_align (n, a8); + p = __builtin_alloca_with_align (n, a16); + p = __builtin_alloca_with_align (n, a32); +} + +template struct X { enum { Align = A }; }; + +template +void test_valid_template (int n) +{ + // Valid alignments are power of 2 positive multiples of CHAR_BIT. + p = __builtin_alloca_with_align (n, A); +} + +template void test_valid_template(int); +template void test_valid_template(int); +template void test_valid_template(int); +template void test_valid_template(int); +template void test_valid_template(int); +template void test_valid_template(int); + +// Exercise the alignment in a dependent context. +template +void test_valid_template_dep (int n) +{ + // Valid alignments are power of 2 positive multiples of CHAR_BIT. + p = __builtin_alloca_with_align (n, X::Align); +} + +template void test_valid_template_dep(int); +template void test_valid_template_dep(int); +template void test_valid_template_dep(int); +template void test_valid_template_dep(int); +template void test_valid_template_dep(int); +template void test_valid_template_dep(int); + +// Invalid size must be rejected (and not cause an ICE). +void test_arg1_non_int (int n) +{ + extern void f (); + + p = __builtin_alloca_with_align ((void*)0, 32); // { dg-error "invalid conversion" } + + p = __builtin_alloca_with_align ("", 32); // { dg-error "invalid conversion" } + p = __builtin_alloca_with_align (L"", 32); // { dg-error "invalid conversion" } + p = __builtin_alloca_with_align (f, 32); // { dg-error "invalid conversion" } +} + +// Non-integer alignment must be rejected. +void test_arg2_non_int (int n) +{ + // Verify the full text of the diagnostic just once. + p = __builtin_alloca_with_align (n, 0.0); // { dg-error "second argument to function .__builtin_alloca_with_align. must be a constant integer power of 2 between .8. and " } + + p = __builtin_alloca_with_align (n, (void*)0); // { dg-error "invalid conversion|must be a constant integer" } + p = __builtin_alloca_with_align (n, ""); // { dg-error "invalid conversion|must be a constant integer" } + p = __builtin_alloca_with_align (n, L""); // { dg-error "invalid conversion|must be a constant integer" } +} + +// Integer alignment that's not a constant expression must be rejected. +void test_arg2_non_const (int n, int a1) +{ + extern const int a2; + static volatile const int a3 = CHAR_BIT; + + p = __builtin_alloca_with_align (n, a1); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, a2); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, a3); // { dg-error "must be a constant integer" } +} + +// Constant integer alignment that's not a power of 2 positive multiple +// of CHAR_BIT must be rejected. +void test_arg2_non_pow2 (int n) +{ + p = __builtin_alloca_with_align (n, INT_MIN); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, -1); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, !1); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, !0); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 0); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 1); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 2); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 3); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 4); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 5); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 6); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 7); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 9); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 10); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 11); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 12); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 13); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 14); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 15); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 17); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 31); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 33); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 63); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, 65); // { dg-error "must be a constant integer" } + p = __builtin_alloca_with_align (n, INT_MAX); // { dg-error "must be a constant integer" } +} + +// Exercise invalid alignment specified by a template argument. +template +void test_invalid_template_1 (int n) +{ + // Valid alignments are power of 2 positive multiples of CHAR_BIT. + p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" } +} + +template void test_invalid_template_1<1>(int); + +template +void test_invalid_template_7 (int n) +{ + p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" } +} + +template void test_invalid_template_7<7>(int); + +template +void test_invalid_template_9 (int n) +{ + p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" } +} + +template void test_invalid_template_9<9>(int); + +// Exercise invalid alignment specified by a template dependent argument. +template +void test_invalid_template_dep_1 (int n) +{ + p = __builtin_alloca_with_align (n, X::Align); // { dg-error "must be a constant integer" } +} + +template void test_invalid_template_dep_1<1>(int);