Commit 744b12b6 by Mark Mitchell Committed by Mark Mitchell

re PR c++/19991 (Enum not accepted in array-size)

	PR c++/19991
	* init.c (integral_constant_value): Iterate if the value of a decl
	is itself a constant.

	PR c++/20152
	* parser.c (cp_parser_class_head): Check for redefintions here.
	* semantics.c (begin_class_definition): Not here.

	PR c++/20153
	* decl2.c (build_anon_union_vars): Add type parameter.
	(finish_anon_union): Pass it.

	PR c++/20148
	* error.c (dump_expr): Do not print the body of a BIND_EXPR.
	Handle STATEMENT_LIST.

	PR c++/19991
	* g++.dg/parse/constant7.C: New test.

	PR c++/20152
	* g++.dg/parse/error27.C: New test.
	* g++.dg/template/qualttp15.C: Adjust error markers.
	* g++.old-deja/g++.other/struct1.C: Likewise.

	PR c++/20153
	* g++.dg/template/error17.C: New test.

	PR c++/20148
	* g++.dg/parser/error26.C: New test.

From-SVN: r95438
parent 90c1d75a
2005-02-22 Mark Mitchell <mark@codesourcery.com> 2005-02-22 Mark Mitchell <mark@codesourcery.com>
PR c++/19991
* init.c (integral_constant_value): Iterate if the value of a decl
is itself a constant.
PR c++/20152
* parser.c (cp_parser_class_head): Check for redefintions here.
* semantics.c (begin_class_definition): Not here.
PR c++/20153
* decl2.c (build_anon_union_vars): Add type parameter.
(finish_anon_union): Pass it.
PR c++/20148
* error.c (dump_expr): Do not print the body of a BIND_EXPR.
Handle STATEMENT_LIST.
PR c++/19883 PR c++/19883
* parser.c (cp_parser_direct_declarator): Always complain about * parser.c (cp_parser_direct_declarator): Always complain about
non-constant array bounds when in a function scope. non-constant array bounds when in a function scope.
......
...@@ -65,7 +65,6 @@ typedef struct priority_info_s { ...@@ -65,7 +65,6 @@ typedef struct priority_info_s {
static void mark_vtable_entries (tree); static void mark_vtable_entries (tree);
static bool maybe_emit_vtables (tree); static bool maybe_emit_vtables (tree);
static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree); static bool acceptable_java_type (tree);
static tree start_objects (int, int); static tree start_objects (int, int);
static void finish_objects (int, int, tree); static void finish_objects (int, int, tree);
...@@ -1072,14 +1071,13 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) ...@@ -1072,14 +1071,13 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl)); SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
} }
/* Walks through the namespace- or function-scope anonymous union OBJECT, /* Walks through the namespace- or function-scope anonymous union
building appropriate ALIAS_DECLs. Returns one of the fields for use in OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs.
the mangled name. */ Returns one of the fields for use in the mangled name. */
static tree static tree
build_anon_union_vars (tree object) build_anon_union_vars (tree type, tree object)
{ {
tree type = TREE_TYPE (object);
tree main_decl = NULL_TREE; tree main_decl = NULL_TREE;
tree field; tree field;
...@@ -1127,7 +1125,7 @@ build_anon_union_vars (tree object) ...@@ -1127,7 +1125,7 @@ build_anon_union_vars (tree object)
decl = pushdecl (decl); decl = pushdecl (decl);
} }
else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
decl = build_anon_union_vars (ref); decl = build_anon_union_vars (TREE_TYPE (field), ref);
else else
decl = 0; decl = 0;
...@@ -1167,7 +1165,7 @@ finish_anon_union (tree anon_union_decl) ...@@ -1167,7 +1165,7 @@ finish_anon_union (tree anon_union_decl)
return; return;
} }
main_decl = build_anon_union_vars (anon_union_decl); main_decl = build_anon_union_vars (type, anon_union_decl);
if (main_decl == NULL_TREE) if (main_decl == NULL_TREE)
{ {
warning ("anonymous union with no members"); warning ("anonymous union with no members");
......
...@@ -1815,18 +1815,14 @@ dump_expr (tree t, int flags) ...@@ -1815,18 +1815,14 @@ dump_expr (tree t, int flags)
dump_decl (t, flags); dump_decl (t, flags);
break; break;
case BIND_EXPR:
case STMT_EXPR: case STMT_EXPR:
case STATEMENT_LIST:
/* We don't yet have a way of dumping statements in a /* We don't yet have a way of dumping statements in a
human-readable format. */ human-readable format. */
pp_string (cxx_pp, "({...})"); pp_string (cxx_pp, "({...})");
break; break;
case BIND_EXPR:
pp_cxx_left_brace (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
pp_cxx_right_brace (cxx_pp);
break;
case LOOP_EXPR: case LOOP_EXPR:
pp_string (cxx_pp, "while (1) { "); pp_string (cxx_pp, "while (1) { ");
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
......
...@@ -1570,17 +1570,17 @@ build_offset_ref (tree type, tree name, bool address_p) ...@@ -1570,17 +1570,17 @@ build_offset_ref (tree type, tree name, bool address_p)
tree tree
integral_constant_value (tree decl) integral_constant_value (tree decl)
{ {
if ((TREE_CODE (decl) == CONST_DECL while ((TREE_CODE (decl) == CONST_DECL
|| (TREE_CODE (decl) == VAR_DECL || (TREE_CODE (decl) == VAR_DECL
/* And so are variables with a 'const' type -- unless they /* And so are variables with a 'const' type -- unless they
are also 'volatile'. */ are also 'volatile'. */
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)) && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))) && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))
&& DECL_INITIAL (decl) && DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node && DECL_INITIAL (decl) != error_mark_node
&& TREE_TYPE (DECL_INITIAL (decl)) && TREE_TYPE (DECL_INITIAL (decl))
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))) && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
return DECL_INITIAL (decl); decl = DECL_INITIAL (decl);
return decl; return decl;
} }
......
...@@ -12842,9 +12842,17 @@ cp_parser_class_head (cp_parser* parser, ...@@ -12842,9 +12842,17 @@ cp_parser_class_head (cp_parser* parser,
CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type); CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
cp_parser_check_class_key (class_key, type); cp_parser_check_class_key (class_key, type);
/* If this type was already complete, and we see another definition,
that's an error. */
if (type != error_mark_node && COMPLETE_TYPE_P (type))
{
error ("redefinition of %q#T", type);
cp_error_at ("previous definition of %q#T", type);
type = error_mark_node;
}
/* We will have entered the scope containing the class; the names of /* We will have entered the scope containing the class; the names of
base classes should be looked up in that context. For example, base classes should be looked up in that context. For example:
given:
struct A { struct B {}; struct C; }; struct A { struct B {}; struct C; };
struct A::C : B {}; struct A::C : B {};
......
...@@ -2125,15 +2125,6 @@ begin_class_definition (tree t) ...@@ -2125,15 +2125,6 @@ begin_class_definition (tree t)
pushtag (make_anon_name (), t, 0); pushtag (make_anon_name (), t, 0);
} }
/* If this type was already complete, and we see another definition,
that's an error. */
if (COMPLETE_TYPE_P (t))
{
error ("redefinition of %q#T", t);
cp_error_at ("previous definition of %q#T", t);
return error_mark_node;
}
/* Update the location of the decl. */ /* Update the location of the decl. */
DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location; DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
......
2005-02-22 Mark Mitchell <mark@codesourcery.com>
PR c++/19991
* g++.dg/parse/constant7.C: New test.
PR c++/20152
* g++.dg/parse/error27.C: New test.
* g++.dg/template/qualttp15.C: Adjust error markers.
* g++.old-deja/g++.other/struct1.C: Likewise.
PR c++/20153
* g++.dg/template/error17.C: New test.
PR c++/20148
* g++.dg/parser/error26.C: New test.
2005-02-22 Diego Novillo <dnovillo@redhat.com> 2005-02-22 Diego Novillo <dnovillo@redhat.com>
PR tree-optimization/20100 PR tree-optimization/20100
......
// PR c++/19991
enum { e = 1 };
template<typename> struct A
{
static const int i = e;
char a[i];
};
// PR c++/20148
// { dg-options "" }
void foo()
{
if (({int c[2];})) ; // { dg-error "\{\.\.\.\}" }
}
void bar()
{
if (({})); // { dg-error "\{\.\.\.\}" }
}
// PR c++/20152
struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "previous definition" }
struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "previous definition" }
struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "" }
struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "" }
KrKDESelectionMode krKDESelectionMode;
// PR c++/20153
template <typename T>
void
foo()
{
union { struct { }; }; // { dg-error "" }
}
...@@ -17,8 +17,8 @@ template <class T> struct X<T::template B> ...@@ -17,8 +17,8 @@ template <class T> struct X<T::template B>
T z; T z;
}; };
template <class T> struct X<T::template B> template <class T> struct X<T::template B> // { dg-error "redefinition" }
{ // { dg-error "redefinition" } {
T z; T z;
}; };
......
...@@ -9,34 +9,34 @@ ...@@ -9,34 +9,34 @@
class Y class Y
{ // { dg-error "" } previous definition { // { dg-error "" } previous definition
}; };
class Y class Y // { dg-error "" } redefinition
{ // { dg-error "" } redefinition {
}; };
template<class T> class X template<class T> class X
{ // { dg-error "" } previous definition { // { dg-error "" } previous definition
}; };
template<class T> class X template<class T> class X // { dg-error "" } redefinition
{ // { dg-error "" } redefinition {
}; };
template<class T> class X<T *> template<class T> class X<T *>
{ // { dg-error "" } previous definition { // { dg-error "" } previous definition
}; };
template<class T> class X<T *> template<class T> class X<T *> // { dg-error "" } redefinition
{ // { dg-error "" } redefinition {
}; };
template<> class X<int> template<> class X<int>
{ // { dg-error "" } previous definition { // { dg-error "" } previous definition
}; };
template<> class X<int> template<> class X<int> // { dg-error "" } redefinition
{ // { dg-error "" } redefinition {
}; };
template<> class X<int *> template<> class X<int *>
{ // { dg-error "" } previous definition { // { dg-error "" } previous definition
}; };
template<> class X<int *> template<> class X<int *> // { dg-error "" } redefinition
{ // { dg-error "" } redefinition {
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment