This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR c++/17524, c++/17685
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 9 Oct 2004 10:57:22 -0700
- Subject: PATCH: PR c++/17524, c++/17685
- Reply-to: mark at codesourcery dot com
This patch fixes two C++ PRs where we ICE'd on erroneous code.
The fix for 17524 involves sharing more code between the template and
non-template processing paths, which is usually a good thing. The
patch for 17685 is straightforward: we were simply failing to
check that only functions can be declared to be operators.
Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-10-09 Mark Mitchell <mark@codesourcery.com>
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-09 Mark Mitchell <mark@codesourcery.com>
PR c++/17524
* g++.dg/template/static9.C: New test.
PR c++/17685
* g++.dg/parse/operator5.C: New test.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1058
diff -c -5 -p -r1.1058 cp-tree.h
*** cp/cp-tree.h 8 Oct 2004 09:33:54 -0000 1.1058
--- cp/cp-tree.h 9 Oct 2004 17:28:02 -0000
*************** extern tree builtin_function (const char
*** 3757,3766 ****
--- 3757,3767 ----
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
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;
/* in decl2.c */
extern bool check_java_method (tree);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1311
diff -c -5 -p -r1.1311 decl.c
*** cp/decl.c 7 Oct 2004 17:48:30 -0000 1.1311
--- cp/decl.c 9 Oct 2004 17:28:03 -0000
*************** check_special_function_return_type (spec
*** 6393,6402 ****
--- 6393,6427 ----
}
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.
DECLSPECS is a chain of tree_list nodes whose value fields
*************** grokdeclarator (const cp_declarator *dec
*** 7741,7769 ****
{
error ("abstract declarator %qT used as declaration", type);
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)
{
! 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;
}
/* Now create the decl, which may be a VAR_DECL, a PARM_DECL
or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */
if (decl_context == PARM || decl_context == CATCHPARM)
{
--- 7766,7790 ----
{
error ("abstract declarator %qT used as declaration", type);
unqualified_id = make_anon_name ();
}
! /* 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)
{
! 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. */
if (decl_context == PARM || decl_context == CATCHPARM)
{
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.933
diff -c -5 -p -r1.933 pt.c
*** cp/pt.c 8 Oct 2004 13:04:04 -0000 1.933
--- cp/pt.c 9 Oct 2004 17:28:11 -0000
*************** tsubst_decl (tree t, tree args, tree typ
*** 6506,6515 ****
--- 6506,6516 ----
if (TREE_CODE (r) == VAR_DECL)
{
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);
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
*************** tsubst_decl (tree t, tree args, tree typ
*** 6546,6558 ****
}
else
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;
default:
--- 6547,6556 ----
Index: testsuite/g++.dg/parse/operator5.C
===================================================================
RCS file: testsuite/g++.dg/parse/operator5.C
diff -N testsuite/g++.dg/parse/operator5.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/operator5.C 9 Oct 2004 17:28:25 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/17685
+
+ struct S {
+ operator int; // { dg-error "" }
+ operator void; // { dg-error "" }
+ };
+
Index: testsuite/g++.dg/template/static9.C
===================================================================
RCS file: testsuite/g++.dg/template/static9.C
diff -N testsuite/g++.dg/template/static9.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/static9.C 9 Oct 2004 17:28:25 -0000
***************
*** 0 ****
--- 1,8 ----
+ // PR c++/17524
+
+ template<typename T> struct A
+ {
+ static const T i = 0; // { dg-error "" }
+ };
+
+ A<void> a; // { dg-error "" }