mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-21 15:31:09 +08:00
P0683R1 - default member initializers for bit-fields
P0683R1 - default member initializers for bit-fields cp/ * cp-tree.h (grokbitfield): Add INIT parameter. * parser.c (cp_parser_constant_expression): Add STRICT_P argument, if true, parse a conditional-expression rather than assignment-expression. (cp_parser_member_declaration): For C++11 and later pass true as STRICT_P to cp_parser_constant_expression. Parse C++2A bitfield NSDMIs. Adjust grokbitfield caller. Handle DECL_INITIAL also for DECL_C_BIT_FIELDs. (cp_parser_objc_class_ivars): Adjust grokbitfield caller. * class.c (check_field_decl): Recurse even for DECL_C_BIT_FIELDs. (check_field_decls): Call check_field_decl even for DECL_C_BIT_FIELDs. * decl2.c (grokbitfield): Add INIT parameter, pass it to cp_finish_decl. * pt.c (tsubst_decl): Handle DECL_INITIAL for all FIELD_DECLs, not just non-bitfields. testsuite/ * g++.dg/ext/bitfield6.C: New test. * g++.dg/cpp2a/bitfield1.C: New test. * g++.dg/cpp2a/bitfield2.C: New test. * g++.dg/cpp2a/bitfield3.C: New test. From-SVN: r253302
This commit is contained in:
parent
7d386d4508
commit
603be0224e
@ -1,5 +1,22 @@
|
||||
2017-09-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
P0683R1 - default member initializers for bit-fields
|
||||
* cp-tree.h (grokbitfield): Add INIT parameter.
|
||||
* parser.c (cp_parser_constant_expression): Add STRICT_P argument,
|
||||
if true, parse a conditional-expression rather than
|
||||
assignment-expression.
|
||||
(cp_parser_member_declaration): For C++11 and later pass true
|
||||
as STRICT_P to cp_parser_constant_expression. Parse C++2A bitfield
|
||||
NSDMIs. Adjust grokbitfield caller. Handle DECL_INITIAL also for
|
||||
DECL_C_BIT_FIELDs.
|
||||
(cp_parser_objc_class_ivars): Adjust grokbitfield caller.
|
||||
* class.c (check_field_decl): Recurse even for DECL_C_BIT_FIELDs.
|
||||
(check_field_decls): Call check_field_decl even for DECL_C_BIT_FIELDs.
|
||||
* decl2.c (grokbitfield): Add INIT parameter, pass it to
|
||||
cp_finish_decl.
|
||||
* pt.c (tsubst_decl): Handle DECL_INITIAL for all FIELD_DECLs, not
|
||||
just non-bitfields.
|
||||
|
||||
* class.c (check_bitfield_decl): Retrieve and clear width from
|
||||
DECL_BIT_FIELD_REPRESENTATIVE rather than DECL_INITIAL.
|
||||
(check_field_decls): Test DECL_BIT_FIELD_REPRESENTATIVE rather than
|
||||
|
@ -3324,7 +3324,7 @@ check_field_decl (tree field,
|
||||
{
|
||||
for (tree fields = TYPE_FIELDS (type); fields;
|
||||
fields = DECL_CHAIN (fields))
|
||||
if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
|
||||
if (TREE_CODE (fields) == FIELD_DECL)
|
||||
any_default_members |= check_field_decl (fields, t,
|
||||
cant_have_const_ctor,
|
||||
no_const_asn_ref);
|
||||
@ -3636,10 +3636,10 @@ check_field_decls (tree t, tree *access_decls,
|
||||
|
||||
/* We set DECL_C_BIT_FIELD in grokbitfield.
|
||||
If the type and width are valid, we'll also set DECL_BIT_FIELD. */
|
||||
if ((! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
|
||||
&& check_field_decl (x, t,
|
||||
cant_have_const_ctor_p,
|
||||
no_const_asn_ref_p))
|
||||
if (DECL_C_BIT_FIELD (x))
|
||||
check_bitfield_decl (x);
|
||||
|
||||
if (check_field_decl (x, t, cant_have_const_ctor_p, no_const_asn_ref_p))
|
||||
{
|
||||
if (any_default_members
|
||||
&& TREE_CODE (t) == UNION_TYPE)
|
||||
|
@ -6159,7 +6159,7 @@ extern void check_member_template (tree);
|
||||
extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
|
||||
tree, bool, tree, tree);
|
||||
extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
|
||||
tree, tree);
|
||||
tree, tree, tree);
|
||||
extern bool any_dependent_type_attributes_p (tree);
|
||||
extern tree cp_reconstruct_complex_type (tree, tree);
|
||||
extern bool attributes_naming_typedef_ok (tree);
|
||||
|
@ -974,14 +974,16 @@ grokfield (const cp_declarator *declarator,
|
||||
}
|
||||
|
||||
/* Like `grokfield', but for bitfields.
|
||||
WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */
|
||||
WIDTH is the width of the bitfield, a constant expression.
|
||||
The other parameters are as for grokfield. */
|
||||
|
||||
tree
|
||||
grokbitfield (const cp_declarator *declarator,
|
||||
cp_decl_specifier_seq *declspecs, tree width,
|
||||
cp_decl_specifier_seq *declspecs, tree width, tree init,
|
||||
tree attrlist)
|
||||
{
|
||||
tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, &attrlist);
|
||||
tree value = grokdeclarator (declarator, declspecs, BITFIELD,
|
||||
init != NULL_TREE, &attrlist);
|
||||
|
||||
if (value == error_mark_node)
|
||||
return NULL_TREE; /* friends went bad. */
|
||||
@ -1036,7 +1038,11 @@ grokbitfield (const cp_declarator *declarator,
|
||||
error ("static member %qD cannot be a bit-field", value);
|
||||
return NULL_TREE;
|
||||
}
|
||||
cp_finish_decl (value, NULL_TREE, false, NULL_TREE, 0);
|
||||
|
||||
int flags = LOOKUP_IMPLICIT;
|
||||
if (init && DIRECT_LIST_INIT_P (init))
|
||||
flags = LOOKUP_NORMAL;
|
||||
cp_finish_decl (value, init, false, NULL_TREE, flags);
|
||||
|
||||
if (width != error_mark_node)
|
||||
{
|
||||
|
@ -2089,7 +2089,7 @@ static enum tree_code cp_parser_assignment_operator_opt
|
||||
static cp_expr cp_parser_expression
|
||||
(cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
|
||||
static cp_expr cp_parser_constant_expression
|
||||
(cp_parser *, bool = false, bool * = NULL);
|
||||
(cp_parser *, bool = false, bool * = NULL, bool = false);
|
||||
static cp_expr cp_parser_builtin_offsetof
|
||||
(cp_parser *);
|
||||
static cp_expr cp_parser_lambda_expression
|
||||
@ -9626,12 +9626,15 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
|
||||
If ALLOW_NON_CONSTANT_P a non-constant expression is silently
|
||||
accepted. If ALLOW_NON_CONSTANT_P is true and the expression is not
|
||||
constant, *NON_CONSTANT_P is set to TRUE. If ALLOW_NON_CONSTANT_P
|
||||
is false, NON_CONSTANT_P should be NULL. */
|
||||
is false, NON_CONSTANT_P should be NULL. If STRICT_P is true,
|
||||
only parse a conditional-expression, otherwise parse an
|
||||
assignment-expression. See below for rationale. */
|
||||
|
||||
static cp_expr
|
||||
cp_parser_constant_expression (cp_parser* parser,
|
||||
bool allow_non_constant_p,
|
||||
bool *non_constant_p)
|
||||
bool *non_constant_p,
|
||||
bool strict_p)
|
||||
{
|
||||
bool saved_integral_constant_expression_p;
|
||||
bool saved_allow_non_integral_constant_expression_p;
|
||||
@ -9665,16 +9668,27 @@ cp_parser_constant_expression (cp_parser* parser,
|
||||
parser->allow_non_integral_constant_expression_p
|
||||
= (allow_non_constant_p || cxx_dialect >= cxx11);
|
||||
parser->non_integral_constant_expression_p = false;
|
||||
/* Although the grammar says "conditional-expression", we parse an
|
||||
"assignment-expression", which also permits "throw-expression"
|
||||
and the use of assignment operators. In the case that
|
||||
ALLOW_NON_CONSTANT_P is false, we get better errors than we would
|
||||
/* Although the grammar says "conditional-expression", when not STRICT_P,
|
||||
we parse an "assignment-expression", which also permits
|
||||
"throw-expression" and the use of assignment operators. In the case
|
||||
that ALLOW_NON_CONSTANT_P is false, we get better errors than we would
|
||||
otherwise. In the case that ALLOW_NON_CONSTANT_P is true, it is
|
||||
actually essential that we look for an assignment-expression.
|
||||
For example, cp_parser_initializer_clauses uses this function to
|
||||
determine whether a particular assignment-expression is in fact
|
||||
constant. */
|
||||
expression = cp_parser_assignment_expression (parser);
|
||||
if (strict_p)
|
||||
{
|
||||
/* Parse the binary expressions (logical-or-expression). */
|
||||
expression = cp_parser_binary_expression (parser, false, false, false,
|
||||
PREC_NOT_OPERATOR, NULL);
|
||||
/* If the next token is a `?' then we're actually looking at
|
||||
a conditional-expression; otherwise we're done. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
|
||||
expression = cp_parser_question_colon_clause (parser, expression);
|
||||
}
|
||||
else
|
||||
expression = cp_parser_assignment_expression (parser);
|
||||
/* Restore the old settings. */
|
||||
parser->integral_constant_expression_p
|
||||
= saved_integral_constant_expression_p;
|
||||
@ -23445,6 +23459,7 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
{
|
||||
tree attributes = NULL_TREE;
|
||||
tree first_attribute;
|
||||
tree initializer;
|
||||
bool is_bitfld = false;
|
||||
bool named_bitfld = false;
|
||||
|
||||
@ -23492,18 +23507,48 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* Get the width of the bitfield. */
|
||||
width = cp_parser_constant_expression (parser);
|
||||
width = cp_parser_constant_expression (parser, false, NULL,
|
||||
cxx_dialect >= cxx11);
|
||||
|
||||
/* Look for attributes that apply to the bitfield after
|
||||
the `:' token and width. This is where GCC used to
|
||||
parse attributes in the past, pedwarn if there is
|
||||
a std attribute. */
|
||||
if (cp_next_tokens_can_be_std_attribute_p (parser))
|
||||
pedwarn (input_location, OPT_Wpedantic,
|
||||
"ISO C++ allows bit-field attributes only before "
|
||||
"the %<:%> token");
|
||||
/* In C++2A and as extension for C++11 and above we allow
|
||||
default member initializers for bit-fields. */
|
||||
initializer = NULL_TREE;
|
||||
if (cxx_dialect >= cxx11
|
||||
&& (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
|
||||
|| cp_lexer_next_token_is (parser->lexer,
|
||||
CPP_OPEN_BRACE)))
|
||||
{
|
||||
location_t loc
|
||||
= cp_lexer_peek_token (parser->lexer)->location;
|
||||
if (cxx_dialect < cxx2a
|
||||
&& !in_system_header_at (loc)
|
||||
&& identifier != NULL_TREE)
|
||||
pedwarn (loc, 0,
|
||||
"default member initializers for bit-fields "
|
||||
"only available with -std=c++2a or "
|
||||
"-std=gnu++2a");
|
||||
|
||||
late_attributes = cp_parser_attributes_opt (parser);
|
||||
initializer = cp_parser_save_nsdmi (parser);
|
||||
if (identifier == NULL_TREE)
|
||||
{
|
||||
error_at (loc, "default member initializer for "
|
||||
"unnamed bit-field");
|
||||
initializer = NULL_TREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Look for attributes that apply to the bitfield after
|
||||
the `:' token and width. This is where GCC used to
|
||||
parse attributes in the past, pedwarn if there is
|
||||
a std attribute. */
|
||||
if (cp_next_tokens_can_be_std_attribute_p (parser))
|
||||
pedwarn (input_location, OPT_Wpedantic,
|
||||
"ISO C++ allows bit-field attributes only "
|
||||
"before the %<:%> token");
|
||||
|
||||
late_attributes = cp_parser_attributes_opt (parser);
|
||||
}
|
||||
|
||||
attributes = chainon (attributes, late_attributes);
|
||||
|
||||
@ -23520,13 +23565,12 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
sfk_none)
|
||||
: NULL,
|
||||
&decl_specifiers,
|
||||
width,
|
||||
width, initializer,
|
||||
attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_declarator *declarator;
|
||||
tree initializer;
|
||||
tree asm_specification;
|
||||
int ctor_dtor_or_conv_p;
|
||||
|
||||
@ -23745,7 +23789,6 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cp_parser_save_default_args (parser, decl);
|
||||
else if (TREE_CODE (decl) == FIELD_DECL
|
||||
&& !DECL_C_BIT_FIELD (decl)
|
||||
&& DECL_INITIAL (decl))
|
||||
/* Add DECL to the queue of NSDMI to be parsed later. */
|
||||
vec_safe_push (unparsed_nsdmis, decl);
|
||||
@ -30086,10 +30129,9 @@ cp_parser_objc_class_ivars (cp_parser* parser)
|
||||
attributes = chainon (prefix_attributes, attributes);
|
||||
|
||||
if (width)
|
||||
/* Create the bitfield declaration. */
|
||||
decl = grokbitfield (declarator, &declspecs,
|
||||
width,
|
||||
attributes);
|
||||
/* Create the bitfield declaration. */
|
||||
decl = grokbitfield (declarator, &declspecs,
|
||||
width, NULL_TREE, attributes);
|
||||
else
|
||||
decl = grokfield (declarator, &declspecs,
|
||||
NULL_TREE, /*init_const_expr_p=*/false,
|
||||
|
@ -12841,7 +12841,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
||||
= tsubst_expr (DECL_BIT_FIELD_REPRESENTATIVE (t), args,
|
||||
complain, in_decl,
|
||||
/*integral_constant_expression_p=*/true);
|
||||
else if (DECL_INITIAL (t))
|
||||
if (DECL_INITIAL (t))
|
||||
{
|
||||
/* Set up DECL_TEMPLATE_INFO so that we can get at the
|
||||
NSDMI in perform_member_init. Still set DECL_INITIAL
|
||||
|
@ -1,3 +1,11 @@
|
||||
2017-09-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
P0683R1 - default member initializers for bit-fields
|
||||
* g++.dg/ext/bitfield6.C: New test.
|
||||
* g++.dg/cpp2a/bitfield1.C: New test.
|
||||
* g++.dg/cpp2a/bitfield2.C: New test.
|
||||
* g++.dg/cpp2a/bitfield3.C: New test.
|
||||
|
||||
2017-09-29 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR target/81481
|
||||
|
77
gcc/testsuite/g++.dg/cpp2a/bitfield1.C
Normal file
77
gcc/testsuite/g++.dg/cpp2a/bitfield1.C
Normal file
@ -0,0 +1,77 @@
|
||||
// P0683R1
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
extern "C" void abort ();
|
||||
int a;
|
||||
const int b = 0;
|
||||
struct S {
|
||||
int c : 5 = 1; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int d : 6 { 2 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int e : true ? 7 : a = 3;
|
||||
int f : (true ? 8 : b) = 4; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int g : (true ? 9 : b) { 5 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int h : 1 || new int { 0 };
|
||||
};
|
||||
#if __cplusplus >= 201402L
|
||||
static_assert (S{}.c == 1);
|
||||
static_assert (S{}.d == 2);
|
||||
static_assert (S{}.e == 0);
|
||||
static_assert (S{}.f == 4);
|
||||
static_assert (S{}.g == 5);
|
||||
static_assert (S{}.h == 0);
|
||||
#endif
|
||||
template <bool V, int W>
|
||||
struct U {
|
||||
int j : W = 7; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int k : W { 8 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int l : V ? 7 : a = 3;
|
||||
int m : (V ? W : b) = 9; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int n : (V ? W : b) { 10 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int o : 1 || new int { 0 };
|
||||
};
|
||||
#if __cplusplus >= 201402L
|
||||
static_assert (U<true, 12>{}.j == 7);
|
||||
static_assert (U<true, 13>{}.k == 8);
|
||||
static_assert (U<true, 10>{}.l == 0);
|
||||
static_assert (U<true, 11>{}.m == 9);
|
||||
static_assert (U<true, 8>{}.n == 10);
|
||||
static_assert (U<true, 7>{}.o == 0);
|
||||
#endif
|
||||
S s;
|
||||
U<true, 10> u;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (s.c != 1 || s.d != 2 || s.e != 0 || s.f != 4 || s.g != 5 || s.h != 0)
|
||||
abort ();
|
||||
s.c = 47; // { dg-warning "overflow in conversion from" }
|
||||
s.d = 47 * 2; // { dg-warning "overflow in conversion from" }
|
||||
s.e = 47 * 4; // { dg-warning "overflow in conversion from" }
|
||||
s.f = 47 * 8; // { dg-warning "overflow in conversion from" }
|
||||
s.g = 47 * 16; // { dg-warning "overflow in conversion from" }
|
||||
s.h = 2; // { dg-warning "overflow in conversion from" }
|
||||
if (s.c != 15 || s.d != 15 * 2 || s.e != 15 * 4 || s.f != 15 * 8 || s.g != 15 * 16 || s.h != 0)
|
||||
abort ();
|
||||
if (u.j != 7 || u.k != 8 || u.l != 0 || u.m != 9 || u.n != 10 || u.o != 0)
|
||||
abort ();
|
||||
u.j = 47 * 32; // { dg-warning "overflow in conversion from" }
|
||||
u.k = 47 * 32; // { dg-warning "overflow in conversion from" }
|
||||
u.l = 47 * 4; // { dg-warning "overflow in conversion from" }
|
||||
u.m = 47 * 32; // { dg-warning "overflow in conversion from" }
|
||||
u.n = 47 * 32; // { dg-warning "overflow in conversion from" }
|
||||
u.o = 2; // { dg-warning "overflow in conversion from" }
|
||||
if (u.j != 15 * 32 || u.k != 15 * 32 || u.l != 15 * 4 || u.m != 15 * 32 || u.n != 15 * 32 || u.o != 0)
|
||||
abort ();
|
||||
s.c = 15;
|
||||
s.d = 15 * 2;
|
||||
s.e = 15 * 4;
|
||||
s.f = 16 * 8;
|
||||
s.g = 15 * 16;
|
||||
u.j = 15 * 32;
|
||||
u.k = 15 * 32;
|
||||
u.l = 15 * 4;
|
||||
u.m = 15 * 32;
|
||||
u.n = 15 * 32;
|
||||
}
|
26
gcc/testsuite/g++.dg/cpp2a/bitfield2.C
Normal file
26
gcc/testsuite/g++.dg/cpp2a/bitfield2.C
Normal file
@ -0,0 +1,26 @@
|
||||
// P0683R1
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
int a;
|
||||
const int b = 0;
|
||||
struct T {
|
||||
int i : true ? 10 : b = 6; // { dg-error "assignment of read-only variable" }
|
||||
int : 4 = 10; // { dg-error "default member initializer for unnamed bit-field" }
|
||||
int : 5 = a + b; // { dg-error "default member initializer for unnamed bit-field" }
|
||||
};
|
||||
template <bool V, int W>
|
||||
struct U {
|
||||
int j : W = 7; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int k : W { 8 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int l : V ? 7 : a = 3; // { dg-error "modification of .a. is not a constant expression" }
|
||||
// { dg-error "width not an integer constant" "" { target *-*-* } .-1 }
|
||||
int m : (V ? W : b) = 9; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-error "zero width for bit-field" "" { target *-*-* } .-1 }
|
||||
int n : (V ? W : b) { 10 }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-error "zero width for bit-field" "" { target *-*-* } .-1 }
|
||||
int o : 1 || new int { 0 };
|
||||
int : 4 = 10; // { dg-error "default member initializer for unnamed bit-field" }
|
||||
int : 5 = a + b; // { dg-error "default member initializer for unnamed bit-field" }
|
||||
};
|
||||
U<false, 10> u;
|
55
gcc/testsuite/g++.dg/cpp2a/bitfield3.C
Normal file
55
gcc/testsuite/g++.dg/cpp2a/bitfield3.C
Normal file
@ -0,0 +1,55 @@
|
||||
// P0683R1
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
int
|
||||
foo ()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int a = foo ();
|
||||
const int b = 0;
|
||||
struct S {
|
||||
int c : 5 = 2 * a; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int d : 6 { c + a }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-warning "narrowing conversion of" "" { target *-*-* } .-1 }
|
||||
int e : true ? 7 : a = 3;
|
||||
int f : (true ? 8 : b) = d + a; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int g : (true ? 9 : b) { f + a }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-warning "narrowing conversion of" "" { target *-*-* } .-1 }
|
||||
int h : 1 || new int { 0 };
|
||||
int i = g + a;
|
||||
};
|
||||
S c;
|
||||
template <bool V, int W>
|
||||
struct U {
|
||||
int j : W = 3 * a; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int k : W { j + a }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-warning "narrowing conversion of" "" { target *-*-* } .-1 }
|
||||
int l : V ? 7 : a = 3;
|
||||
int m : (V ? W : b) = k + a; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
int n : (V ? W : b) { m + a }; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
// { dg-warning "narrowing conversion of" "" { target *-*-* } .-1 }
|
||||
int o : 1 || new int { 0 };
|
||||
int p = n + a;
|
||||
};
|
||||
U<true, 10> d;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
a = 1;
|
||||
if (c.c != 4 || c.d != 6 || c.e != 0 || c.f != 8 || c.g != 10 || c.h != 0 || c.i != 12)
|
||||
abort ();
|
||||
if (d.j != 6 || d.k != 8 || d.l != 0 || d.m != 10 || d.n != 12 || d.o != 0 || d.p != 14)
|
||||
abort ();
|
||||
S s;
|
||||
U<true, 10> u;
|
||||
if (s.c != 2 || s.d != 3 || s.f != 4 || s.g != 5 || s.i != 6)
|
||||
abort ();
|
||||
if (u.j != 3 || u.k != 4 || u.m != 5 || u.n != 6 || u.p != 7)
|
||||
abort ();
|
||||
}
|
15
gcc/testsuite/g++.dg/ext/bitfield6.C
Normal file
15
gcc/testsuite/g++.dg/ext/bitfield6.C
Normal file
@ -0,0 +1,15 @@
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
struct S {
|
||||
char a [[gnu::packed]] = 1; // { dg-warning "attribute ignored for field of type" }
|
||||
char b [[gnu::packed]] : 8;
|
||||
char c [[gnu::packed]] : 8 = 2; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
};
|
||||
template <typename U>
|
||||
struct T {
|
||||
U d [[gnu::packed]] = 1; // { dg-warning "attribute ignored for field of type" }
|
||||
U e [[gnu::packed]] : 8;
|
||||
U f [[gnu::packed]] : 8 = 2; // { dg-warning "default member initializers for bit-fields only available with" "" { target c++17_down } }
|
||||
};
|
||||
T<char> t;
|
Loading…
x
Reference in New Issue
Block a user