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
This commit is contained in:
Mark Mitchell 2005-02-23 05:30:48 +00:00 committed by Mark Mitchell
parent 90c1d75a9b
commit 744b12b65f
13 changed files with 109 additions and 48 deletions

View File

@ -1,5 +1,21 @@
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
* parser.c (cp_parser_direct_declarator): Always complain about
non-constant array bounds when in a function scope.

View File

@ -65,7 +65,6 @@ typedef struct priority_info_s {
static void mark_vtable_entries (tree);
static bool maybe_emit_vtables (tree);
static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree);
static tree start_objects (int, int);
static void finish_objects (int, int, tree);
@ -1072,14 +1071,13 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
}
/* Walks through the namespace- or function-scope anonymous union OBJECT,
building appropriate ALIAS_DECLs. Returns one of the fields for use in
the mangled name. */
/* Walks through the namespace- or function-scope anonymous union
OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs.
Returns one of the fields for use in the mangled name. */
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 field;
@ -1127,7 +1125,7 @@ build_anon_union_vars (tree object)
decl = pushdecl (decl);
}
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
decl = 0;
@ -1167,7 +1165,7 @@ finish_anon_union (tree anon_union_decl)
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)
{
warning ("anonymous union with no members");

View File

@ -1815,18 +1815,14 @@ dump_expr (tree t, int flags)
dump_decl (t, flags);
break;
case BIND_EXPR:
case STMT_EXPR:
case STATEMENT_LIST:
/* We don't yet have a way of dumping statements in a
human-readable format. */
pp_string (cxx_pp, "({...})");
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:
pp_string (cxx_pp, "while (1) { ");
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);

View File

@ -1570,17 +1570,17 @@ build_offset_ref (tree type, tree name, bool address_p)
tree
integral_constant_value (tree decl)
{
if ((TREE_CODE (decl) == CONST_DECL
|| (TREE_CODE (decl) == VAR_DECL
/* And so are variables with a 'const' type -- unless they
are also 'volatile'. */
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_TYPE (DECL_INITIAL (decl))
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
return DECL_INITIAL (decl);
while ((TREE_CODE (decl) == CONST_DECL
|| (TREE_CODE (decl) == VAR_DECL
/* And so are variables with a 'const' type -- unless they
are also 'volatile'. */
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_TYPE (DECL_INITIAL (decl))
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
decl = DECL_INITIAL (decl);
return decl;
}

View File

@ -12842,9 +12842,17 @@ cp_parser_class_head (cp_parser* parser,
CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_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
base classes should be looked up in that context. For example,
given:
base classes should be looked up in that context. For example:
struct A { struct B {}; struct C; };
struct A::C : B {};

View File

@ -2125,15 +2125,6 @@ begin_class_definition (tree t)
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. */
DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;

View File

@ -1,3 +1,19 @@
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>
PR tree-optimization/20100

View File

@ -0,0 +1,9 @@
// PR c++/19991
enum { e = 1 };
template<typename> struct A
{
static const int i = e;
char a[i];
};

View File

@ -0,0 +1,12 @@
// PR c++/20148
// { dg-options "" }
void foo()
{
if (({int c[2];})) ; // { dg-error "\{\.\.\.\}" }
}
void bar()
{
if (({})); // { dg-error "\{\.\.\.\}" }
}

View File

@ -0,0 +1,7 @@
// 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;

View File

@ -0,0 +1,8 @@
// PR c++/20153
template <typename T>
void
foo()
{
union { struct { }; }; // { dg-error "" }
}

View File

@ -17,8 +17,8 @@ template <class T> struct X<T::template B>
T z;
};
template <class T> struct X<T::template B>
{ // { dg-error "redefinition" }
template <class T> struct X<T::template B> // { dg-error "redefinition" }
{
T z;
};

View File

@ -9,34 +9,34 @@
class Y
{ // { dg-error "" } previous definition
};
class Y
{ // { dg-error "" } redefinition
class Y // { dg-error "" } redefinition
{
};
template<class T> class X
{ // { dg-error "" } previous definition
};
template<class T> class X
{ // { dg-error "" } redefinition
template<class T> class X // { dg-error "" } redefinition
{
};
template<class T> class X<T *>
{ // { dg-error "" } previous definition
};
template<class T> class X<T *>
{ // { dg-error "" } redefinition
template<class T> class X<T *> // { dg-error "" } redefinition
{
};
template<> class X<int>
{ // { dg-error "" } previous definition
};
template<> class X<int>
{ // { dg-error "" } redefinition
template<> class X<int> // { dg-error "" } redefinition
{
};
template<> class X<int *>
{ // { dg-error "" } previous definition
};
template<> class X<int *>
{ // { dg-error "" } redefinition
template<> class X<int *> // { dg-error "" } redefinition
{
};