Commit 95f79357 by Zack Weinberg

c-decl.c (start_decl): Unconditionally issue error for 'typedef foo = bar'.

gcc:
	* c-decl.c (start_decl): Unconditionally issue error for
	'typedef foo = bar'.
	(finish_decl): Remove special case for TYPE_DECL with initializer.

	* doc/extend.texi: Delete "Naming Types" section.  Change all
	cross-references to that section to refer to "Typeof" instead.
	Add the useful safe-max()-macro example from "Naming Types" to
	"Typeof", rewritten using that extension.

gcc/cp:
	* decl.c (start_decl): Unconditionally issue error for
	'typedef foo = bar'.
	(cp_finish_decl): Remove special case for TYPE_DECL with initializer.
	(grokdeclarator): Remove redundant error for 'typedef foo = bar'.

gcc/testsuite:
	* g++.dg/ext/typedef-init.C: New test.
	* gcc.dg/typedef-init.c: New test.

From-SVN: r57995
parent 10a38dba
2002-10-09 Zack Weinberg <zack@codesourcery.com>
PR c/7353
* c-decl.c (start_decl): Unconditionally issue error for
'typedef foo = bar'.
(finish_decl): Remove special case for TYPE_DECL with initializer.
* doc/extend.texi: Delete "Naming Types" section. Change all
cross-references to that section to refer to "Typeof" instead.
Add the useful safe-max()-macro example from "Naming Types" to
"Typeof", rewritten using that extension. Add some compatibility
notes to "Typeof."
2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* loop.c: Revert 2002-08-15 change. * loop.c: Revert 2002-08-15 change.
......
...@@ -2821,15 +2821,9 @@ start_decl (declarator, declspecs, initialized, attributes) ...@@ -2821,15 +2821,9 @@ start_decl (declarator, declspecs, initialized, attributes)
switch (TREE_CODE (decl)) switch (TREE_CODE (decl))
{ {
case TYPE_DECL: case TYPE_DECL:
/* typedef foo = bar means give foo the same type as bar. error ("typedef `%s' is initialized",
We haven't parsed bar yet, so `finish_decl' will fix that up. IDENTIFIER_POINTER (DECL_NAME (decl)));
Any other case of an initialization in a TYPE_DECL is an error. */ initialized = 0;
if (pedantic || list_length (declspecs) > 1)
{
error ("typedef `%s' is initialized",
IDENTIFIER_POINTER (DECL_NAME (decl)));
initialized = 0;
}
break; break;
case FUNCTION_DECL: case FUNCTION_DECL:
...@@ -2988,16 +2982,7 @@ finish_decl (decl, init, asmspec_tree) ...@@ -2988,16 +2982,7 @@ finish_decl (decl, init, asmspec_tree)
init = 0; init = 0;
if (init) if (init)
{ store_init_value (decl, init);
if (TREE_CODE (decl) != TYPE_DECL)
store_init_value (decl, init);
else
{
/* typedef foo = bar; store the type of bar as the type of foo. */
TREE_TYPE (decl) = TREE_TYPE (init);
DECL_INITIAL (decl) = init = 0;
}
}
/* Deduce size of array from initialization, if not already known */ /* Deduce size of array from initialization, if not already known */
if (TREE_CODE (type) == ARRAY_TYPE if (TREE_CODE (type) == ARRAY_TYPE
......
2002-10-09 Zack Weinberg <zack@codesourcery.com>
* decl.c (start_decl): Unconditionally issue error for
'typedef foo = bar'.
(cp_finish_decl): Remove special case for TYPE_DECL with initializer.
(grokdeclarator): Remove redundant error for 'typedef foo = bar'.
2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl2.c (prune_vtable_vardecl): Delete unused function. * decl2.c (prune_vtable_vardecl): Delete unused function.
...@@ -84,7 +91,7 @@ ...@@ -84,7 +91,7 @@
2002-10-02 Matt Austern <austern@apple.com> 2002-10-02 Matt Austern <austern@apple.com>
* decl.c (walk_vtables_r): Fixed typo that caused result to * decl.c (walk_vtables_r): Fixed typo that caused result to
never get a nonzero value. never get a nonzero value.
2002-10-02 Roger Sayle <roger@eyesopen.com> 2002-10-02 Roger Sayle <roger@eyesopen.com>
PR optimization/6627 PR optimization/6627
...@@ -98,7 +105,7 @@ ...@@ -98,7 +105,7 @@
* class.c (check_field_decls): Changed warning about const member * class.c (check_field_decls): Changed warning about const member
variables so that it doesn't get issued for a class aggregate. variables so that it doesn't get issued for a class aggregate.
2002-10-01 Mark Mitchell <mark@codesourcery.com> 2002-10-01 Mark Mitchell <mark@codesourcery.com>
* decl.c (cp_finish_decl): Make sure array types are laid out, * decl.c (cp_finish_decl): Make sure array types are laid out,
...@@ -181,12 +188,12 @@ ...@@ -181,12 +188,12 @@
(dfs_unuse_fields): Likewise. (dfs_unuse_fields): Likewise.
* tree.c (pod_type_p): Handle error_mark_node. * tree.c (pod_type_p): Handle error_mark_node.
(zero_init_p): Likewise. (zero_init_p): Likewise.
* typeck.c (lookup_anon_field): Skip FIELD_DECLs for base * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base
subobjects. subobjects.
* typeck2.c (store_init_value): Remove #if 0'd code. * typeck2.c (store_init_value): Remove #if 0'd code.
(force_store_init_value): Remove. (force_store_init_value): Remove.
(process_init_constructor): Use build_zero_init. (process_init_constructor): Use build_zero_init.
2002-09-29 Nathan Sidwell <nathan@codesourcery.com> 2002-09-29 Nathan Sidwell <nathan@codesourcery.com>
PR c++/7788 PR c++/7788
...@@ -214,7 +221,7 @@ ...@@ -214,7 +221,7 @@
even number of bytes when computing the size without virtual even number of bytes when computing the size without virtual
bases. bases.
* cp/cp-tree.h (abi_version_at_least): New macro. * cp/cp-tree.h (abi_version_at_least): New macro.
2002-09-21 Kazu Hirata <kazu@cs.umass.edu> 2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
* ChangeLog: Follow spelling conventions. * ChangeLog: Follow spelling conventions.
......
...@@ -7290,14 +7290,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) ...@@ -7290,14 +7290,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
switch (TREE_CODE (decl)) switch (TREE_CODE (decl))
{ {
case TYPE_DECL: case TYPE_DECL:
/* typedef foo = bar means give foo the same type as bar. error ("typedef `%D' is initialized", decl);
We haven't parsed bar yet, so `cp_finish_decl' will fix that up. initialized = 0;
Any other case of an initialization in a TYPE_DECL is an error. */
if (pedantic || list_length (declspecs) > 1)
{
error ("typedef `%D' is initialized", decl);
initialized = 0;
}
break; break;
case FUNCTION_DECL: case FUNCTION_DECL:
...@@ -8156,12 +8150,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags) ...@@ -8156,12 +8150,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
/* Take care of TYPE_DECLs up front. */ /* Take care of TYPE_DECLs up front. */
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
{ {
if (init && DECL_INITIAL (decl))
{
/* typedef foo = bar; store the type of bar as the type of foo. */
TREE_TYPE (decl) = type = TREE_TYPE (init);
DECL_INITIAL (decl) = init = NULL_TREE;
}
if (type != error_mark_node if (type != error_mark_node
&& IS_AGGR_TYPE (type) && DECL_NAME (decl)) && IS_AGGR_TYPE (type) && DECL_NAME (decl))
{ {
...@@ -11365,9 +11353,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -11365,9 +11353,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE); inlinep, friendp, raises != NULL_TREE);
if (initialized)
error ("typedef declaration includes an initializer");
return decl; return decl;
} }
......
...@@ -427,7 +427,6 @@ extensions, accepted by GCC in C89 mode and in C++. ...@@ -427,7 +427,6 @@ extensions, accepted by GCC in C89 mode and in C++.
* Labels as Values:: Getting pointers to labels, and computed gotos. * Labels as Values:: Getting pointers to labels, and computed gotos.
* Nested Functions:: As in Algol and Pascal, lexical scoping of functions. * Nested Functions:: As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls:: Dispatching a call to another function. * Constructing Calls:: Dispatching a call to another function.
* Naming Types:: Giving a name to the type of some expression.
* Typeof:: @code{typeof}: referring to the type of an expression. * Typeof:: @code{typeof}: referring to the type of an expression.
* Lvalues:: Using @samp{?:}, @samp{,} and casts in lvalues. * Lvalues:: Using @samp{?:}, @samp{,} and casts in lvalues.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression. * Conditionals:: Omitting the middle operand of a @samp{?:} expression.
...@@ -538,8 +537,7 @@ the value of an enumeration constant, the width of a bit-field, or ...@@ -538,8 +537,7 @@ the value of an enumeration constant, the width of a bit-field, or
the initial value of a static variable. the initial value of a static variable.
If you don't know the type of the operand, you can still do this, but you If you don't know the type of the operand, you can still do this, but you
must use @code{typeof} (@pxref{Typeof}) or type naming (@pxref{Naming must use @code{typeof} (@pxref{Typeof}).
Types}).
Statement expressions are not supported fully in G++, and their fate Statement expressions are not supported fully in G++, and their fate
there is unclear. (It is possible that they will become fully supported there is unclear. (It is possible that they will become fully supported
...@@ -888,29 +886,6 @@ the containing function. You should specify, for @var{result}, a value ...@@ -888,29 +886,6 @@ the containing function. You should specify, for @var{result}, a value
returned by @code{__builtin_apply}. returned by @code{__builtin_apply}.
@end deftypefn @end deftypefn
@node Naming Types
@section Naming an Expression's Type
@cindex naming types
You can give a name to the type of an expression using a @code{typedef}
declaration with an initializer. Here is how to define @var{name} as a
type name for the type of @var{exp}:
@example
typedef @var{name} = @var{exp};
@end example
This is useful in conjunction with the statements-within-expressions
feature. Here is how the two together can be used to define a safe
``maximum'' macro that operates on any arithmetic type:
@example
#define max(a,b) \
(@{typedef _ta = (a), _tb = (b); \
_ta _a = (a); _tb _b = (b); \
_a > _b ? _a : _b; @})
@end example
@cindex underscores in variables in macros @cindex underscores in variables in macros
@cindex @samp{_} in variables in macros @cindex @samp{_} in variables in macros
@cindex local variables in macros @cindex local variables in macros
...@@ -962,6 +937,21 @@ A @code{typeof}-construct can be used anywhere a typedef name could be ...@@ -962,6 +937,21 @@ A @code{typeof}-construct can be used anywhere a typedef name could be
used. For example, you can use it in a declaration, in a cast, or inside used. For example, you can use it in a declaration, in a cast, or inside
of @code{sizeof} or @code{typeof}. of @code{sizeof} or @code{typeof}.
@code{typeof} is often useful in conjunction with the
statements-within-expressions feature. Here is how the two together can
be used to define a safe ``maximum'' macro that operates on any
arithmetic type and evaluates each of its arguments exactly once:
@example
#define max(a,b) \
(@{ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; @})
@end example
@noindent
Some more examples of the use of @code{typeof}:
@itemize @bullet @itemize @bullet
@item @item
This declares @code{y} with the type of what @code{x} points to. This declares @code{y} with the type of what @code{x} points to.
...@@ -1011,6 +1001,26 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4 ...@@ -1011,6 +1001,26 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
pointers to @code{char}. pointers to @code{char}.
@end itemize @end itemize
@emph{Compatibility Note:} In addition to @code{typeof}, GCC 2 supported
a more limited extension which permitted one to write
@example
typedef @var{T} = @var{expr};
@end example
@noindent
with the effect of declaring @var{T} to have the type of the expression
@var{expr}. This extension does not work with GCC 3 (versions between
3.0 and 3.2 will crash; 3.2.1 and later give an error). Code which
relies on it should be rewritten to use @code{typeof}:
@example
typedef typeof(@var{expr}) @var{T};
@end example
@noindent
This will work with all versions of GCC@.
@node Lvalues @node Lvalues
@section Generalized Lvalues @section Generalized Lvalues
@cindex compound expressions as lvalues @cindex compound expressions as lvalues
...@@ -6827,12 +6837,12 @@ the minimum value of variables @var{i} and @var{j}. ...@@ -6827,12 +6837,12 @@ the minimum value of variables @var{i} and @var{j}.
However, side effects in @code{X} or @code{Y} may cause unintended However, side effects in @code{X} or @code{Y} may cause unintended
behavior. For example, @code{MIN (i++, j++)} will fail, incrementing behavior. For example, @code{MIN (i++, j++)} will fail, incrementing
the smaller counter twice. A GNU C extension allows you to write safe the smaller counter twice. The GNU C @code{typeof} extension allows you
macros that avoid this kind of problem (@pxref{Naming Types,,Naming an to write safe macros that avoid this kind of problem (@pxref{Typeof}).
Expression's Type}). However, writing @code{MIN} and @code{MAX} as However, writing @code{MIN} and @code{MAX} as macros also forces you to
macros also forces you to use function-call notation for a use function-call notation for a fundamental arithmetic operation.
fundamental arithmetic operation. Using GNU C++ extensions, you can Using GNU C++ extensions, you can write @w{@samp{int min = i <? j;}}
write @w{@samp{int min = i <? j;}} instead. instead.
Since @code{<?} and @code{>?} are built into the compiler, they properly Since @code{<?} and @code{>?} are built into the compiler, they properly
handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}} handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}}
......
2002-10-09 Zack Weinberg <zack@codesourcery.com>
* g++.dg/ext/typedef-init.C: New test.
* gcc.dg/typedef-init.c: New test.
2002-10-09 Neil Booth <neil@daikokuya.co.uk> 2002-10-09 Neil Booth <neil@daikokuya.co.uk>
* gcc.dg/cpp/paste13.c: New test. * gcc.dg/cpp/paste13.c: New test.
......
/* { dg-do compile } */
/* { dg-options "-fpermissive" } // suppress default -pedantic-errors */
/* This code used to be a legitimate, if dubious, extension. However,
it's been broken since GCC 3.0 (caused ICE) and we have now removed
the extension. See PR c/7353.
C++ issues a warning in addition to the error, since this construct
appears to be a case of implicit int (forbidden in std. C++) until
we get to the equals sign. */
typedef A = 0; /* { dg-error "initialized" "typedef A = B" } */
/* { dg-warning "no type" "also warns" { target *-*-* } 12 } */
A a; /* { dg-bogus "" "no error cascade" } */
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } // suppress default -pedantic-errors */
/* This code used to be a legitimate, if dubious, extension. However,
it's been broken since GCC 3.0 (caused ICE) and we have now removed
the extension. See PR c/7353. */
typedef A = 0; /* { dg-error "initialized" "typedef A = B" } */
A a; /* { dg-bogus "" "no error cascade" } */
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