From: Zack Weinberg Date: Wed, 9 Oct 2002 21:27:38 +0000 (+0000) Subject: c-decl.c (start_decl): Unconditionally issue error for 'typedef foo = bar'. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=95f79357c5e37b27626a5513b612f8b598e5e8ce;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c2bdf92..fbe859a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2002-10-09 Zack Weinberg + + 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 * loop.c: Revert 2002-08-15 change. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index dba2737..60fade4 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -2821,15 +2821,9 @@ start_decl (declarator, declspecs, initialized, attributes) switch (TREE_CODE (decl)) { case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - error ("typedef `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } + error ("typedef `%s' is initialized", + IDENTIFIER_POINTER (DECL_NAME (decl))); + initialized = 0; break; case FUNCTION_DECL: @@ -2988,16 +2982,7 @@ finish_decl (decl, init, asmspec_tree) init = 0; if (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; - } - } + store_init_value (decl, init); /* Deduce size of array from initialization, if not already known */ if (TREE_CODE (type) == ARRAY_TYPE diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 49d65cd..edb8694 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2002-10-09 Zack Weinberg + + * 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 * decl2.c (prune_vtable_vardecl): Delete unused function. @@ -84,7 +91,7 @@ 2002-10-02 Matt Austern * decl.c (walk_vtables_r): Fixed typo that caused result to never get a nonzero value. - + 2002-10-02 Roger Sayle PR optimization/6627 @@ -98,7 +105,7 @@ * class.c (check_field_decls): Changed warning about const member variables so that it doesn't get issued for a class aggregate. - + 2002-10-01 Mark Mitchell * decl.c (cp_finish_decl): Make sure array types are laid out, @@ -181,12 +188,12 @@ (dfs_unuse_fields): Likewise. * tree.c (pod_type_p): Handle error_mark_node. (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. * typeck2.c (store_init_value): Remove #if 0'd code. (force_store_init_value): Remove. (process_init_constructor): Use build_zero_init. - + 2002-09-29 Nathan Sidwell PR c++/7788 @@ -214,7 +221,7 @@ even number of bytes when computing the size without virtual bases. * cp/cp-tree.h (abi_version_at_least): New macro. - + 2002-09-21 Kazu Hirata * ChangeLog: Follow spelling conventions. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e095f07..8ab8a5e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7290,14 +7290,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) switch (TREE_CODE (decl)) { case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `cp_finish_decl' will fix that up. - 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; - } + error ("typedef `%D' is initialized", decl); + initialized = 0; break; case FUNCTION_DECL: @@ -8156,12 +8150,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags) /* Take care of TYPE_DECLs up front. */ 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 && IS_AGGR_TYPE (type) && DECL_NAME (decl)) { @@ -11365,9 +11353,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); - if (initialized) - error ("typedef declaration includes an initializer"); - return decl; } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a95098f..f583a67 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -427,7 +427,6 @@ extensions, accepted by GCC in C89 mode and in C++. * Labels as Values:: Getting pointers to labels, and computed gotos. * Nested Functions:: As in Algol and Pascal, lexical scoping of functions. * 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. * Lvalues:: Using @samp{?:}, @samp{,} and casts in lvalues. * 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 the initial value of a static variable. 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 -Types}). +must use @code{typeof} (@pxref{Typeof}). Statement expressions are not supported fully in G++, and their fate 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 returned by @code{__builtin_apply}. @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 @samp{_} in 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 used. For example, you can use it in a declaration, in a cast, or inside 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 @item 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 pointers to @code{char}. @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 @section Generalized Lvalues @cindex compound expressions as lvalues @@ -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 behavior. For example, @code{MIN (i++, j++)} will fail, incrementing -the smaller counter twice. A GNU C extension allows you to write safe -macros that avoid this kind of problem (@pxref{Naming Types,,Naming an -Expression's Type}). However, writing @code{MIN} and @code{MAX} as -macros also forces you to use function-call notation for a -fundamental arithmetic operation. Using GNU C++ extensions, you can -write @w{@samp{int min = i ?} are built into the compiler, they properly handle expressions with side-effects; @w{@samp{int min = i++ + + * g++.dg/ext/typedef-init.C: New test. + * gcc.dg/typedef-init.c: New test. + 2002-10-09 Neil Booth * gcc.dg/cpp/paste13.c: New test. diff --git a/gcc/testsuite/g++.dg/ext/typedef-init.C b/gcc/testsuite/g++.dg/ext/typedef-init.C new file mode 100644 index 0000000..5602783 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typedef-init.C @@ -0,0 +1,14 @@ +/* { 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" } */ diff --git a/gcc/testsuite/gcc.dg/typedef-init.c b/gcc/testsuite/gcc.dg/typedef-init.c new file mode 100644 index 0000000..9cb4830b --- /dev/null +++ b/gcc/testsuite/gcc.dg/typedef-init.c @@ -0,0 +1,9 @@ +/* { 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" } */