c-tree.h (struct c_declspecs): Add const_p, volatile_p and restrict_p.

* c-tree.h (struct c_declspecs): Add const_p, volatile_p and
	restrict_p.
	(struct c_declarator): Change u.array.quals and pointer_quals to
	int.  Add u.array.attrs.
	(quals_from_declspecs): New.
	* c-decl.c (quals_from_declspecs): New.
	(shadow_tag_warned): Give more specific message for useless type
	qualifiers.
	(build_array_declarator, set_array_declarator_inner,
	grokdeclarator, make_pointer_declarator, build_null_declspecs,
	declspecs_add_qual): Update for changed structures.

testsuite:
	* gcc.dg/declspec-12.c: New test.

From-SVN: r87500
This commit is contained in:
Joseph Myers 2004-09-14 19:59:38 +01:00 committed by Joseph Myers
parent 67dd4a9377
commit 3b53cddc38
5 changed files with 129 additions and 61 deletions

View File

@ -1,3 +1,17 @@
2004-09-14 Joseph S. Myers <jsm@polyomino.org.uk>
* c-tree.h (struct c_declspecs): Add const_p, volatile_p and
restrict_p.
(struct c_declarator): Change u.array.quals and pointer_quals to
int. Add u.array.attrs.
(quals_from_declspecs): New.
* c-decl.c (quals_from_declspecs): New.
(shadow_tag_warned): Give more specific message for useless type
qualifiers.
(build_array_declarator, set_array_declarator_inner,
grokdeclarator, make_pointer_declarator, build_null_declspecs,
declspecs_add_qual): Update for changed structures.
2004-09-14 Jeff Law <law@redhat.com>
* tree-ssa-dom.c (stmts_to_rescan): Move from a block-local

View File

@ -2771,6 +2771,14 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
warned = 2;
}
if (!warned && !in_system_header && (declspecs->const_p
|| declspecs->volatile_p
|| declspecs->restrict_p))
{
warning ("useless type qualifier in empty declaration");
warned = 2;
}
if (!warned && !in_system_header && declspecs->specbits)
{
warning ("useless keyword or type name in empty declaration");
@ -2784,6 +2792,32 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
}
}
/* Return the qualifiers from SPECS as a bitwise OR of TYPE_QUAL_*
bits. SPECS represents declaration specifiers that the grammar
only permits to contain type qualifiers and attributes. */
int
quals_from_declspecs (const struct c_declspecs *specs)
{
int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
| (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
| (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0));
gcc_assert (!specs->type
&& !specs->decl_attr
&& !specs->specbits
&& specs->storage_class == csc_none
&& !specs->typedef_p
&& !specs->typedef_signed_p
&& !specs->deprecated_p
&& !specs->explicit_int_p
&& !specs->explicit_char_p
&& !specs->long_long_p
&& !specs->inline_p
&& !specs->thread_p);
return quals;
}
/* Construct an array declarator. EXPR is the expression inside [], or
NULL_TREE. QUALS are the type qualifiers inside the [] (to be applied
to the pointer to which a parameter array is converted). STATIC_P is
@ -2802,7 +2836,16 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
declarator->kind = cdk_array;
declarator->declarator = 0;
declarator->u.array.dimen = expr;
declarator->u.array.quals = quals;
if (quals)
{
declarator->u.array.attrs = quals->attrs;
declarator->u.array.quals = quals_from_declspecs (quals);
}
else
{
declarator->u.array.attrs = NULL_TREE;
declarator->u.array.quals = 0;
}
declarator->u.array.static_p = static_p;
declarator->u.array.vla_unspec_p = vla_unspec_p;
if (pedantic && !flag_isoc99)
@ -2830,7 +2873,8 @@ set_array_declarator_inner (struct c_declarator *decl,
struct c_declarator *inner, bool abstract_p)
{
decl->declarator = inner;
if (abstract_p && (decl->u.array.quals != NULL
if (abstract_p && (decl->u.array.quals != TYPE_UNQUALIFIED
|| decl->u.array.attrs != NULL_TREE
|| decl->u.array.static_p))
error ("static or type qualifiers in abstract declarator");
return decl;
@ -3644,7 +3688,8 @@ grokdeclarator (const struct c_declarator *declarator,
bool funcdef_syntax = false;
int size_varies = 0;
tree decl_attr = NULL_TREE;
struct c_declspecs *array_ptr_quals = 0;
int array_ptr_quals = TYPE_UNQUALIFIED;
tree array_ptr_attrs = NULL_TREE;
int array_parm_static = 0;
tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL;
@ -3897,11 +3942,9 @@ grokdeclarator (const struct c_declarator *declarator,
duplicate qualifiers should be diagnosed in this case, but it
seems most appropriate to do so). */
element_type = strip_array_types (type);
constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (element_type);
restrictp
= !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (element_type);
volatilep
= !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type);
constp = declspecs->const_p + TYPE_READONLY (element_type);
restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
if (pedantic && !flag_isoc99)
{
if (constp > 1)
@ -4021,13 +4064,16 @@ grokdeclarator (const struct c_declarator *declarator,
array or function or pointer, and DECLARATOR has had its
outermost layer removed. */
if (array_ptr_quals != NULL || array_parm_static)
if (array_ptr_quals != TYPE_UNQUALIFIED
|| array_ptr_attrs != NULL_TREE
|| array_parm_static)
{
/* Only the innermost declarator (making a parameter be of
array type which is converted to pointer type)
may have static or type qualifiers. */
error ("static or type qualifiers in non-parameter array declarator");
array_ptr_quals = NULL;
array_ptr_quals = TYPE_UNQUALIFIED;
array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
}
@ -4062,6 +4108,7 @@ grokdeclarator (const struct c_declarator *declarator,
tree index_type = c_common_signed_type (sizetype);
array_ptr_quals = declarator->u.array.quals;
array_ptr_attrs = declarator->u.array.attrs;
array_parm_static = declarator->u.array.static_p;
declarator = declarator->declarator;
@ -4214,10 +4261,13 @@ grokdeclarator (const struct c_declarator *declarator,
layout_type (type);
if (decl_context != PARM
&& (array_ptr_quals != NULL || array_parm_static))
&& (array_ptr_quals != TYPE_UNQUALIFIED
|| array_ptr_attrs != NULL_TREE
|| array_parm_static))
{
error ("static or type qualifiers in non-parameter array declarator");
array_ptr_quals = NULL;
array_ptr_quals = TYPE_UNQUALIFIED;
array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
}
break;
@ -4306,31 +4356,13 @@ grokdeclarator (const struct c_declarator *declarator,
pedwarn ("ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
type = build_pointer_type (type);
/* Process type qualifiers (such as const or volatile)
that were given inside the `*'. */
if (declarator->u.pointer_quals)
{
int pbits = declarator->u.pointer_quals->specbits;
/* The grammar should only permit qualifiers here. */
gcc_assert (!declarator->u.pointer_quals->type
&& !(pbits & ~((1 << (int) RID_CONST)
| (1 << (int) RID_VOLATILE)
| (1 << (int) RID_RESTRICT))));
constp = !!(pbits & (1 << (int) RID_CONST));
volatilep = !!(pbits & (1 << (int) RID_VOLATILE));
restrictp = !!(pbits & (1 << (int) RID_RESTRICT));
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
}
type_quals = declarator->u.pointer_quals;
declarator = declarator->declarator;
break;
@ -4445,29 +4477,12 @@ grokdeclarator (const struct c_declarator *declarator,
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
type_quals = TYPE_UNQUALIFIED;
if (array_ptr_quals)
{
int apqbits = array_ptr_quals->specbits;
type_quals = array_ptr_quals;
/* We don't yet implement attributes in this context. */
if (array_ptr_quals->attrs != NULL_TREE)
warning ("attributes in parameter array declarator ignored");
/* We don't yet implement attributes in this context. */
if (array_ptr_attrs != NULL_TREE)
warning ("attributes in parameter array declarator ignored");
/* The grammar should only permit qualifiers here. */
gcc_assert (!array_ptr_quals->type
&& !(apqbits & ~((1 << (int) RID_CONST)
| (1 << (int) RID_VOLATILE)
| (1 << (int) RID_RESTRICT))));
constp = !!(apqbits & (1 << (int) RID_CONST));
volatilep = !!(apqbits & (1 << (int) RID_VOLATILE));
restrictp = !!(apqbits & (1 << (int) RID_RESTRICT));
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
}
size_varies = 0;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
@ -6724,18 +6739,19 @@ make_pointer_declarator (struct c_declspecs *type_quals_attrs,
struct c_declarator *target)
{
tree attrs;
int quals = 0;
struct c_declarator *itarget = target;
struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
if (type_quals_attrs)
{
attrs = type_quals_attrs->attrs;
type_quals_attrs->attrs = NULL_TREE;
quals = quals_from_declspecs (type_quals_attrs);
if (attrs != NULL_TREE)
itarget = build_attrs_declarator (attrs, target);
}
ret->kind = cdk_pointer;
ret->declarator = itarget;
ret->u.pointer_quals = type_quals_attrs;
ret->u.pointer_quals = quals;
return ret;
}
@ -6760,6 +6776,9 @@ build_null_declspecs (void)
ret->long_long_p = false;
ret->inline_p = false;
ret->thread_p = false;
ret->const_p = false;
ret->volatile_p = false;
ret->restrict_p = false;
return ret;
}
@ -6770,14 +6789,30 @@ struct c_declspecs *
declspecs_add_qual (struct c_declspecs *specs, tree qual)
{
enum rid i;
bool dupe = false;
specs->non_sc_seen_p = true;
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual);
gcc_assert (i == RID_CONST || i == RID_VOLATILE || i == RID_RESTRICT);
if ((specs->specbits & (1 << (int) i)) && pedantic && !flag_isoc99)
switch (i)
{
case RID_CONST:
dupe = specs->const_p;
specs->const_p = true;
break;
case RID_VOLATILE:
dupe = specs->volatile_p;
specs->volatile_p = true;
break;
case RID_RESTRICT:
dupe = specs->restrict_p;
specs->restrict_p = true;
break;
default:
gcc_unreachable ();
}
if (dupe && pedantic && !flag_isoc99)
pedwarn ("duplicate %qs", IDENTIFIER_POINTER (qual));
specs->specbits |= 1 << (int) i;
return specs;
}

View File

@ -180,6 +180,12 @@ struct c_declspecs {
BOOL_BITFIELD inline_p : 1;
/* Whether "__thread" was specified. */
BOOL_BITFIELD thread_p : 1;
/* Whether "const" was specified. */
BOOL_BITFIELD const_p : 1;
/* Whether "volatile" was specified. */
BOOL_BITFIELD volatile_p : 1;
/* Whether "restrict" was specified. */
BOOL_BITFIELD restrict_p : 1;
};
/* The various kinds of declarators in C. */
@ -225,15 +231,17 @@ struct c_declarator {
struct {
/* The array dimension, or NULL for [] and [*]. */
tree dimen;
/* The qualifiers (and attributes, currently ignored) inside []. */
struct c_declspecs *quals;
/* The qualifiers inside []. */
int quals;
/* The attributes (currently ignored) inside []. */
tree attrs;
/* Whether [static] was used. */
BOOL_BITFIELD static_p : 1;
/* Whether [*] was used. */
BOOL_BITFIELD vla_unspec_p : 1;
} array;
/* For pointers, the qualifiers on the pointer type. */
struct c_declspecs *pointer_quals;
int pointer_quals;
/* For attributes. */
tree attrs;
} u;
@ -297,6 +305,7 @@ extern void c_expand_body (tree);
extern void c_init_decl_processing (void);
extern void c_dup_lang_specific_decl (tree);
extern void c_print_identifier (FILE *, tree, int);
extern int quals_from_declspecs (const struct c_declspecs *);
extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
bool, bool);
extern tree build_enumerator (tree, tree);

View File

@ -1,3 +1,7 @@
2004-09-14 Joseph S. Myers <jsm@polyomino.org.uk>
* gcc.dg/declspec-12.c: New test.
2004-09-14 Bud Davis <bdavis9659@comcast.net>
* gfortran.dg/pr17090.f90: Add directives to test.

View File

@ -0,0 +1,6 @@
/* Test type qualifier in empty declaration: OK but useless. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-pedantic-errors" } */
const struct foo; /* { dg-warning "warning: useless type qualifier in empty declaration" } */