diff options
author | Simon Martin <simartin@users.sourceforge.net> | 2007-06-07 19:59:33 +0000 |
---|---|---|
committer | Simon Martin <simartin@gcc.gnu.org> | 2007-06-07 19:59:33 +0000 |
commit | c1ae8be51fb22104066600fdddeaf94b004e63c8 (patch) | |
tree | c9bfce8481cc2ab5d947f7ccd7de24217b53132e /gcc | |
parent | 20967296dc0517322a6058ec55491de9707c0c34 (diff) | |
download | gcc-c1ae8be51fb22104066600fdddeaf94b004e63c8.zip gcc-c1ae8be51fb22104066600fdddeaf94b004e63c8.tar.gz gcc-c1ae8be51fb22104066600fdddeaf94b004e63c8.tar.bz2 |
re PR c++/30759 (initializer-list accepted for object of non-POD type)
gcc/
2007-06-07 Simon Martin <simartin@users.sourceforge.net>
PR c++/30759
* c-common.h (flag_cpp0x): Replaced by...
(cxx_dialect): ... this new variable specifying the C++ dialect that
is used.
* c-common.c (flag_cpp0x): Removed.
(cxx_dialect): Defined.
* c-cppbuiltin.c (c_cpp_builtins): flag_cpp0x rewritten in terms of
cxx_dialect.
* c-opts.c (c_common_post_options): Likewise.
(set_std_cxx98): Set cxx_dialect to cxx98.
(set_std_cxx0x): Set cxx_dialect to cxx0x.
gcc/cp/
2007-06-07 Simon Martin <simartin@users.sourceforge.net>
PR c++/30759
* decl.c (check_initializer): Report an error when a brace enclosed
initializer is used for a non-aggregate type in C++98.
(redeclaration_error_message): Rewrote flag_cpp0x in terms of
cxx_dialect.
(grokdeclarator): Likewise.
(move_fn_p): Likewise.
* typeck.c (check_return_expr): Likewise.
* call.c (reference_binding): Likewise.
* error.c (cp_cpp_error): Likewise.
* pt.c (check_default_tmpl_args): Likewise.
(tsubst): Likewise.
* lex.c (init_reswords): Likewise.
* parser.c (p_parser_primary_expression): Likewise.
(TOKEN_PRECEDENCE): Likewise.
(cp_parser_init_declarator): Likewise.
(cp_parser_ptr_operator): Likewise.
(cp_parser_parameter_declaration): Likewise.
(cp_parser_enclosed_template_argument_list): Likewise.
(cp_parser_skip_to_end_of_template_parameter_list): Likewise.
(cp_parser_next_token_ends_template_argument_p): Likewise.
gcc/testsuite/
2007-06-07 Simon Martin <simartin@users.sourceforge.net>
PR c++/30759
* g++.dg/init/brace6.C: New test.
From-SVN: r125539
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c-common.c | 5 | ||||
-rw-r--r-- | gcc/c-common.h | 14 | ||||
-rw-r--r-- | gcc/c-cppbuiltin.c | 2 | ||||
-rw-r--r-- | gcc/c-opts.c | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 37 | ||||
-rw-r--r-- | gcc/cp/error.c | 2 | ||||
-rw-r--r-- | gcc/cp/lex.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 26 | ||||
-rw-r--r-- | gcc/cp/pt.c | 14 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/brace6.C | 25 |
15 files changed, 136 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba69834..30e9f6e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2007-06-07 Simon Martin <simartin@users.sourceforge.net> + + PR c++/30759 + * c-common.h (flag_cpp0x): Replaced by... + (cxx_dialect): ... this new variable specifying the C++ dialect that + is used. + * c-common.c (flag_cpp0x): Removed. + (cxx_dialect): Defined. + * c-cppbuiltin.c (c_cpp_builtins): flag_cpp0x rewritten in terms of + cxx_dialect. + * c-opts.c (c_common_post_options): Likewise. + (set_std_cxx98): Set cxx_dialect to cxx98. + (set_std_cxx0x): Set cxx_dialect to cxx0x. + 2007-06-06 Geoffrey Keating <geoffk@apple.com> Hui-May Chang <hm.chang@apple.com> diff --git a/gcc/c-common.c b/gcc/c-common.c index b903218..f17bb7f 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -406,10 +406,9 @@ int flag_access_control = 1; int flag_check_new; -/* Nonzero if we want to allow the use of experimental features that - are likely to become part of C++0x. */ +/* The C++ dialect being used. C++98 is the default. */ -int flag_cpp0x = 0; +enum cxx_dialect cxx_dialect = cxx98; /* Nonzero if we want the new ISO rules for pushing a new scope for `for' initialization variables. diff --git a/gcc/c-common.h b/gcc/c-common.h index c60ce56..62032c6 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -543,10 +543,18 @@ extern int flag_access_control; extern int flag_check_new; -/* Nonzero if we want to allow the use of experimental features that - are likely to become part of C++0x. */ +/* The supported C++ dialects. */ + +enum cxx_dialect { + /* C++98 */ + cxx98, + /* Experimental features that are likely to become part of + C++0x. */ + cxx0x +}; -extern int flag_cpp0x; +/* The C++ dialect being used. C++98 is the default. */ +extern enum cxx_dialect cxx_dialect; /* Nonzero if we want the new ISO rules for pushing a new scope for `for' initialization variables. diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c index 1b52da0..19bb47c 100644 --- a/gcc/c-cppbuiltin.c +++ b/gcc/c-cppbuiltin.c @@ -419,7 +419,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__GXX_WEAK__=0"); if (warn_deprecated) cpp_define (pfile, "__DEPRECATED"); - if (flag_cpp0x) + if (cxx_dialect == cxx0x) cpp_define (pfile, "__GXX_EXPERIMENTAL_CXX0X__"); } /* Note that we define this for C as well, so that we know if diff --git a/gcc/c-opts.c b/gcc/c-opts.c index b11e671..d0fafc6 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -1145,7 +1145,7 @@ c_common_post_options (const char **pfilename) /* If we're allowing C++0x constructs, don't warn about C++0x compatibility problems. */ - if (flag_cpp0x) + if (cxx_dialect == cxx0x) warn_cxx0x_compat = 0; if (flag_preprocess_only) @@ -1610,6 +1610,7 @@ set_std_cxx98 (int iso) flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; + cxx_dialect = cxx98; } /* Set the C++ 0x working draft "standard" (without GNU extensions if ISO). */ @@ -1620,7 +1621,7 @@ set_std_cxx0x (int iso) flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; - flag_cpp0x = 1; + cxx_dialect = cxx0x; } /* Handle setting implicit to ON. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1f04e28..bc6bdd1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2007-06-07 Simon Martin <simartin@users.sourceforge.net> + + PR c++/30759 + * decl.c (check_initializer): Report an error when a brace enclosed + initializer is used for a non-aggregate type in C++98. + (redeclaration_error_message): Rewrote flag_cpp0x in terms of + cxx_dialect. + (grokdeclarator): Likewise. + (move_fn_p): Likewise. + * typeck.c (check_return_expr): Likewise. + * call.c (reference_binding): Likewise. + * error.c (cp_cpp_error): Likewise. + * pt.c (check_default_tmpl_args): Likewise. + (tsubst): Likewise. + * lex.c (init_reswords): Likewise. + * parser.c (p_parser_primary_expression): Likewise. + (TOKEN_PRECEDENCE): Likewise. + (cp_parser_init_declarator): Likewise. + (cp_parser_ptr_operator): Likewise. + (cp_parser_parameter_declaration): Likewise. + (cp_parser_enclosed_template_argument_list): Likewise. + (cp_parser_skip_to_end_of_template_parameter_list): Likewise. + (cp_parser_next_token_ends_template_argument_p): Likewise. + 2007-06-04 Simon Baldwin <simonb@google.com> * decl.c (grokdeclarator): Readability change. Moved case labels diff --git a/gcc/cp/call.c b/gcc/cp/call.c index deae301..6e6be64 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1160,7 +1160,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) DR391. */ if (compatible_p && (lvalue_p - || (flag_cpp0x + || ((cxx_dialect != cxx98) && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto)) && CLASS_TYPE_P (from)))) { diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2f65f1c..f7a9f1e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2161,7 +2161,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit. */ - if (flag_cpp0x + if ((cxx_dialect != cxx98) && TREE_CODE (ot) == FUNCTION_DECL && DECL_FRIEND_P (ot) && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), /*is_primary=*/1, /*is_partial=*/0, @@ -4777,14 +4777,29 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else /* There is no way to make a variable-sized class type in GNU C++. */ gcc_assert (TREE_CONSTANT (TYPE_SIZE (type))); - - if (!CP_AGGREGATE_TYPE_P (type) - && init && BRACE_ENCLOSED_INITIALIZER_P (init) - && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) != 1) + + if (init && BRACE_ENCLOSED_INITIALIZER_P (init)) { - error ("scalar object %qD requires one element in initializer", decl); - TREE_TYPE (decl) = error_mark_node; - return NULL_TREE; + int init_len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)); + if (SCALAR_TYPE_P (type)) + { + if (init_len != 1) + { + error ("scalar object %qD requires one element in initializer", + decl); + TREE_TYPE (decl) = error_mark_node; + return NULL_TREE; + } + } + else if ((cxx_dialect == cxx98) && !CP_AGGREGATE_TYPE_P (type)) + { + /* A non-aggregate that is not a scalar cannot be initialized + via an initializer-list in C++98. */ + error ("braces around initializer for non-aggregate type %qT", + type); + TREE_TYPE (decl) = error_mark_node; + return NULL_TREE; + } } if (TREE_CODE (decl) == CONST_DECL) @@ -7871,7 +7886,7 @@ grokdeclarator (const cp_declarator *declarator, are still forbidden, occurs below. Reasoning behind the change can be found in DR106, DR540, and the rvalue reference proposals. */ - else if (!flag_cpp0x) + else if (cxx_dialect == cxx98) { error ("cannot declare reference to %q#T", type); type = TREE_TYPE (type); @@ -9217,8 +9232,8 @@ move_fn_p (tree d) gcc_assert (DECL_FUNCTION_MEMBER_P (d)); - if (!flag_cpp0x) - /* There are no move constructors if we aren't in C++0x mode. */ + if (cxx_dialect == cxx98) + /* There are no move constructors if we are in C++98 mode. */ return false; if (TREE_CODE (d) == TEMPLATE_DECL diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 6121436..512944b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2549,7 +2549,7 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, void maybe_warn_variadic_templates (void) { - if (!flag_cpp0x && !in_system_header) + if ((cxx_dialect == cxx98) && !in_system_header) /* We really want to suppress this warning in system headers, because libstdc++ uses variadic templates even when we aren't in C++0x mode. */ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 080a843..f1dc864 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -334,7 +334,7 @@ init_reswords (void) int mask = ((flag_no_asm ? D_ASM : 0) | D_OBJC | (flag_no_gnu_keywords ? D_EXT : 0) - | (flag_cpp0x ? 0 : D_CXX0X)); + | ((cxx_dialect == cxx0x) ? 0 : D_CXX0X)); ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX); for (i = 0; i < ARRAY_SIZE (reswords); i++) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c1a3276..7b41a56 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3109,7 +3109,7 @@ cp_parser_primary_expression (cp_parser *parser, /* C++0x only: A ">>" treated like two ">" tokens, in a template-argument-list. */ && (next_token->type != CPP_RSHIFT - || !flag_cpp0x + || (cxx_dialect == cxx98) || parser->greater_than_is_operator_p)) cast_p = false; } @@ -5887,11 +5887,11 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) The binops_by_token map is used to get the tree codes for each <token> type. binary-expressions are associated according to a precedence table. */ -#define TOKEN_PRECEDENCE(token) \ -(((token->type == CPP_GREATER \ - || (flag_cpp0x && token->type == CPP_RSHIFT)) \ - && !parser->greater_than_is_operator_p) \ - ? PREC_NOT_OPERATOR \ +#define TOKEN_PRECEDENCE(token) \ +(((token->type == CPP_GREATER \ + || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)) \ + && !parser->greater_than_is_operator_p) \ + ? PREC_NOT_OPERATOR \ : binops_by_token[token->type].prec) static tree @@ -11974,7 +11974,8 @@ cp_parser_init_declarator (cp_parser* parser, ((is_parenthesized_init || !is_initialized) ? 0 : LOOKUP_ONLYCONVERTING)); } - else if (flag_cpp0x && friend_p && decl && TREE_CODE (decl) == FUNCTION_DECL) + else if ((cxx_dialect != cxx98) && friend_p + && decl && TREE_CODE (decl) == FUNCTION_DECL) /* Core issue #226 (C++0x only): A default template-argument shall not be specified in a friend class template declaration. */ @@ -12590,7 +12591,8 @@ cp_parser_ptr_operator (cp_parser* parser, code = INDIRECT_REF; else if (token->type == CPP_AND) code = ADDR_EXPR; - else if (flag_cpp0x && token->type == CPP_AND_AND) /* C++0x only */ + else if ((cxx_dialect != cxx98) && + token->type == CPP_AND_AND) /* C++0x only */ code = NON_LVALUE_EXPR; if (code != ERROR_MARK) @@ -13273,7 +13275,7 @@ cp_parser_parameter_declaration (cp_parser *parser, break; case CPP_RSHIFT: - if (!flag_cpp0x) + if (cxx_dialect == cxx98) break; /* Fall through for C++0x, which treats the `>>' operator like two `>' tokens in certain @@ -16808,7 +16810,7 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) a '>>' instead, it's probably just a typo. */ if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT)) { - if (flag_cpp0x) + if (cxx_dialect != cxx98) { /* In C++0x, a `>>' in a template argument list or cast expression is considered to be two separate `>' @@ -17338,7 +17340,7 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser) break; case CPP_RSHIFT: - if (!flag_cpp0x) + if (cxx_dialect == cxx98) /* C++0x views the `>>' operator as two `>' tokens, but C++98 does not. */ break; @@ -17460,7 +17462,7 @@ cp_parser_next_token_ends_template_argument_p (cp_parser *parser) return (token->type == CPP_COMMA || token->type == CPP_GREATER || token->type == CPP_ELLIPSIS - || (flag_cpp0x && token->type == CPP_RSHIFT)); + || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)); } /* Returns TRUE iff the n-th token is a "<", or the n-th is a "[" and the diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 47f3c0d..f3210dd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3447,7 +3447,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, /* Core issue 226 (C++0x only): the following only applies to class templates. */ - if (!flag_cpp0x || TREE_CODE (decl) != FUNCTION_DECL) + if ((cxx_dialect == cxx98) || TREE_CODE (decl) != FUNCTION_DECL) { /* [temp.param] @@ -3482,7 +3482,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, } } - if ((!flag_cpp0x && TREE_CODE (decl) != TYPE_DECL) + if (((cxx_dialect == cxx98) && TREE_CODE (decl) != TYPE_DECL) || is_partial || !is_primary || is_friend_decl) @@ -3510,7 +3510,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, msg = "default template arguments may not be used in function template friend re-declaration"; else if (is_friend_decl) msg = "default template arguments may not be used in function template friend declarations"; - else if (TREE_CODE (decl) == FUNCTION_DECL && !flag_cpp0x) + else if (TREE_CODE (decl) == FUNCTION_DECL && (cxx_dialect == cxx98)) msg = "default template arguments may not be used in function templates"; else if (is_partial) msg = "default template arguments may not be used in partial specializations"; @@ -8736,7 +8736,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) during instantiation is no longer a cause for failure. We only enforce this check in strict C++98 mode. */ if ((TREE_CODE (type) == REFERENCE_TYPE - && ((!flag_cpp0x && flag_iso) || code != REFERENCE_TYPE)) + && (((cxx_dialect == cxx98) && flag_iso) || code != REFERENCE_TYPE)) || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE)) { static location_t last_loc; @@ -11537,9 +11537,9 @@ type_unification_real (tree tparms, If a template argument has not been deduced, its default template argument, if any, is used. - When we are not in C++0x mode (i.e., !flag_cpp0x), - TREE_PURPOSE will either be NULL_TREE or ERROR_MARK_NODE, - so we do not need to explicitly check flag_cpp0x here. */ + When we are in C++98 mode, TREE_PURPOSE will either + be NULL_TREE or ERROR_MARK_NODE, so we do not need + to explicitly check cxx_dialect here. */ if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i))) { tree arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)), diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4219e69..f17aa80 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6733,7 +6733,7 @@ check_return_expr (tree retval, bool *no_warning) /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes treated as an rvalue for the purposes of overload resolution to favor move constructors over copy constructors. */ - if (flag_cpp0x + if ((cxx_dialect != cxx98) && named_return_value_okay_p /* The variable must not have the `volatile' qualifier. */ && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d364c9a..0c650e7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-06-07 Simon Martin <simartin@users.sourceforge.net> + + PR c++/30759 + * g++.dg/init/brace6.C: New test. + 2007-06-07 Geoffrey Keating <geoffk@apple.com> * gcc.dg/attr-weakref-1-darwin.c: Run on all Darwin platforms. diff --git a/gcc/testsuite/g++.dg/init/brace6.C b/gcc/testsuite/g++.dg/init/brace6.C new file mode 100644 index 0000000..ffb7011 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/brace6.C @@ -0,0 +1,25 @@ +/* PR c++/30759 */ +/* { dg-do "compile" } */ + +struct A { + A(int) { } +}; + +struct B { + B(const B&); + int b; +}; + +struct C {}; + +struct D { int c; }; + +int main() +{ + int i = { 1 }; + int j = { 1, 2 }; /* { dg-error "requires one element" } */ + A a = { 6 }; /* { dg-error "initializer for non" } */ + B b = { 6 }; /* { dg-error "initializer for non" } */ + C c = { 6 }; /* { dg-error "too many initializers" } */ + D d = { 6 }; +} |