From 62e19030ce1bb924f906a4ef4992d87461180eab Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 9 Oct 2004 17:33:02 +0000 Subject: [PATCH] re PR c++/17524 (ICE with initializing a variable of type void) PR c++/17524 * cp-tree.h (check_var_type): New function. * decl.c (check_var_type): New function, split out from ... (grokdeclarator): ... here. * pt.c (tsubst_decl): Use check_var_type. PR c++/17685 * decl.c (grokdeclarator): Disallow declarations of operators as PR c++/17524 * g++.dg/template/static9.C: New test. PR c++/17685 * g++.dg/parse/operator5.C: New test. From-SVN: r88820 --- gcc/cp/ChangeLog | 12 ++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 53 +++++++++++++++++-------- gcc/cp/pt.c | 4 +- gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/g++.dg/parse/operator5.C | 7 ++++ gcc/testsuite/g++.dg/template/static9.C | 8 ++++ 7 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/operator5.C create mode 100644 gcc/testsuite/g++.dg/template/static9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ca408ecdef6..5c4c7c84681 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2004-10-09 Mark Mitchell + + PR c++/17524 + * cp-tree.h (check_var_type): New function. + * decl.c (check_var_type): New function, split out from ... + (grokdeclarator): ... here. + * pt.c (tsubst_decl): Use check_var_type. + + PR c++/17685 + * decl.c (grokdeclarator): Disallow declarations of operators as + non-functions. + 2004-10-08 Volker Reichelt PR c++/17868 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 826bd51cf29..ca0722a442e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3759,6 +3759,7 @@ extern void warn_extern_redeclared_static (tree, tree); extern const char *cxx_comdat_group (tree); extern bool cp_missing_noreturn_ok_p (tree); extern void initialize_artificial_var (tree, tree); +extern tree check_var_type (tree, tree); extern bool have_extern_spec; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 919b619cc83..fa50faae994 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6395,6 +6395,31 @@ check_special_function_return_type (special_function_kind sfk, return type; } +/* A variable or data member (whose unqualified name is IDENTIFIER) + has been declared with the indicated TYPE. If the TYPE is not + acceptable, issue an error message and return a type to use for + error-recovery purposes. */ + +tree +check_var_type (tree identifier, tree type) +{ + if (VOID_TYPE_P (type)) + { + if (!identifier) + error ("unnamed variable or field declared void"); + else if (TREE_CODE (identifier) == IDENTIFIER_NODE) + { + gcc_assert (!IDENTIFIER_OPNAME_P (identifier)); + error ("variable or field %qE declared void", identifier); + } + else + error ("variable or field declared void"); + type = integer_type_node; + } + + return type; +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -7743,25 +7768,21 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id = make_anon_name (); } - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM) + /* Only functions may be declared using an operator-function-id. */ + if (unqualified_id + && IDENTIFIER_OPNAME_P (unqualified_id) + && TREE_CODE (type) != FUNCTION_TYPE + && TREE_CODE (type) != METHOD_TYPE) { - if (! unqualified_id) - error ("unnamed variable or field declared void"); - else if (TREE_CODE (unqualified_id) == IDENTIFIER_NODE) - { - gcc_assert (!IDENTIFIER_OPNAME_P (unqualified_id)); - error ("variable or field %qs declared void", name); - } - else - error ("variable or field declared void"); - type = integer_type_node; + error ("declaration of %qD as non-function", unqualified_id); + return error_mark_node; } + /* We don't check parameter types here because we can emit a better + error message later. */ + if (decl_context != PARM) + type = check_var_type (unqualified_id, type); + /* Now create the decl, which may be a VAR_DECL, a PARM_DECL or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9a869eaecd2..c794e35bf4e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6508,6 +6508,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) type = complete_type (type); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); + type = check_var_type (DECL_NAME (r), type); } else if (DECL_SELF_REFERENCE_P (t)) SET_DECL_SELF_REFERENCE_P (r); @@ -6548,9 +6549,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) register_local_specialization (r, t); TREE_CHAIN (r) = NULL_TREE; - if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type)) - cp_error_at ("instantiation of %qD as type %qT", r, type); - /* Compute the size, alignment, etc. of R. */ layout_decl (r, 0); } break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28d0a1121b1..b91dec57d8b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2004-10-09 Mark Mitchell + + PR c++/17524 + * g++.dg/template/static9.C: New test. + + PR c++/17685 + * g++.dg/parse/operator5.C: New test. + 2004-10-09 Roger Sayle PR middle-end/17894 diff --git a/gcc/testsuite/g++.dg/parse/operator5.C b/gcc/testsuite/g++.dg/parse/operator5.C new file mode 100644 index 00000000000..3e453bdf358 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/operator5.C @@ -0,0 +1,7 @@ +// PR c++/17685 + +struct S { + operator int; // { dg-error "" } + operator void; // { dg-error "" } +}; + diff --git a/gcc/testsuite/g++.dg/template/static9.C b/gcc/testsuite/g++.dg/template/static9.C new file mode 100644 index 00000000000..4575708e4e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static9.C @@ -0,0 +1,8 @@ +// PR c++/17524 + +template struct A +{ + static const T i = 0; // { dg-error "" } +}; + +A a; // { dg-error "" }