re PR c/7353 (Compiler dies on known working code (as of gcc 3.0))
PR c/7353 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: r57997
This commit is contained in:
parent
6959d4f74b
commit
2297583bb8
|
@ -1,3 +1,16 @@
|
|||
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-02 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR opt/7124
|
||||
|
@ -19,7 +32,7 @@ Wed Oct 9 19:09:13 CEST 2002 Jan Hubicka <jh@suse.cz>
|
|||
PR doc/7484
|
||||
* doc/invoke.texi (Option Summary): List
|
||||
-Wmissing-declarations as a C only option.
|
||||
|
||||
|
||||
2002-10-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/sparc/t-linux64 (MULTILIB_OPTIONS): Remove
|
||||
|
@ -189,13 +202,13 @@ Thu Sep 5 00:34:33 2002 J"orn Rennecke <joern.rennecke@superh.com>
|
|||
PR middle-end/7151
|
||||
* config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
|
||||
(movdi reg/reg split): Match only on sparc32, and v9 when int regs.
|
||||
|
||||
|
||||
2002-10-01 David S. Miller <davem@redhat.com>
|
||||
Jan Hubicka <jh@suse.cz>
|
||||
|
||||
|
||||
* reload1.c (gen_reload:SECONDARY_MEMORY_NEEDED): Handle SUBREG.
|
||||
* reload.c (push_reload:SECONDARY_MEMORY_NEEDED): Likewise.
|
||||
|
||||
|
||||
2002-09-30 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
|
||||
|
|
23
gcc/c-decl.c
23
gcc/c-decl.c
|
@ -3485,15 +3485,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:
|
||||
|
@ -3642,16 +3636,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
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2002-10-09 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
PR c/7353
|
||||
* 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-03 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/7754
|
||||
|
@ -379,7 +387,7 @@
|
|||
2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/5719
|
||||
* decl.c (grok_op_properties): Assignment ops don't have to return
|
||||
* decl.c (grok_op_properties): Assignment ops don't have to return
|
||||
by value. operator% should.
|
||||
|
||||
2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
@ -463,7 +471,7 @@
|
|||
(finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
|
||||
* semantics.c (begin_gobal_stmt_expr): Adjust call to
|
||||
expand_start_stmt_expr.
|
||||
|
||||
|
||||
2002-04-15 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (register_dtor_fn): Pass the address of dso_handle, not
|
||||
|
@ -492,11 +500,11 @@
|
|||
|
||||
* typeck.c (type_after_usual_arithmetic_conversions):
|
||||
If two types have the same variant, return immediately.
|
||||
When two floating-point operands are the same precision:
|
||||
When two floating-point operands are the same precision:
|
||||
convert to float if one of the operands is float;
|
||||
if neither operand is one of the standard types, return the type
|
||||
of the first operand.
|
||||
|
||||
|
||||
2002-04-12 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* decl.c (duplicate_decls): Don't try to unify an implicit typedef
|
||||
|
@ -554,7 +562,7 @@
|
|||
set before checking it.
|
||||
|
||||
PR c++/6179
|
||||
* method.c (implicitly_declare_fn): Pass unqualified type to
|
||||
* method.c (implicitly_declare_fn): Pass unqualified type to
|
||||
synthesize_exception_spec.
|
||||
|
||||
2002-04-03 Jason Merrill <jason@redhat.com>
|
||||
|
@ -619,7 +627,7 @@
|
|||
PR c++/4884
|
||||
* call.c (build_op_delete_call): Allow for the fact the placement
|
||||
may be a COMPOUND_EXPR.
|
||||
|
||||
|
||||
2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/5682
|
||||
|
@ -673,7 +681,7 @@
|
|||
|
||||
2002-03-18 Ashif Harji <asharji@uwaterloo.ca>
|
||||
|
||||
* lang-specs.h (compiler default_compilers): Add
|
||||
* lang-specs.h (compiler default_compilers): Add
|
||||
-no-integrated-cpp flag to invoke an external cpp.
|
||||
|
||||
2002-03-18 Jason Merrill <jason@redhat.com>
|
||||
|
@ -790,7 +798,7 @@
|
|||
with pointer to member conversions.
|
||||
|
||||
2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
|
||||
|
||||
|
||||
* cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
|
||||
conditional return void.
|
||||
|
||||
|
@ -824,7 +832,7 @@
|
|||
* decl.c (finish_function): Only warn about missing return
|
||||
statement with -Wreturn-type.
|
||||
|
||||
2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
|
||||
2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
|
||||
|
||||
PR c++/4093
|
||||
* cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
|
||||
|
@ -878,7 +886,7 @@
|
|||
|
||||
2002-02-19 Jason Merrill <jason@redhat.com>
|
||||
|
||||
ABI change: Mangle `void (A::*)() const' as
|
||||
ABI change: Mangle `void (A::*)() const' as
|
||||
M1AKFvvE, not MK1AFvvE.
|
||||
* mangle.c (write_function_type): Write cv-quals for member
|
||||
function type here.
|
||||
|
@ -953,14 +961,14 @@
|
|||
(coerce_template_template_parms, convert_template_argument,
|
||||
coerce_template_parms, maybe_get_template_decl_from_type_decl,
|
||||
lookup_template_class, tsubst_friend_function, tsubst_friend_class,
|
||||
instantiate_class_template, tsubst_template_arg_vector,
|
||||
tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
|
||||
instantiate_class_template, tsubst_template_arg_vector,
|
||||
tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
|
||||
tsubst_decl, tsubst_arg_types, tsubst_function_type,
|
||||
tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
|
||||
tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
|
||||
instantiate_template, fn_type_unification,
|
||||
resolve_overloaded_unification, verify_class_unification,
|
||||
unify, get_bindings_real, do_type_instantiation,
|
||||
regenerate_decl_from_template, instantiate_decl,
|
||||
resolve_overloaded_unification, verify_class_unification,
|
||||
unify, get_bindings_real, do_type_instantiation,
|
||||
regenerate_decl_from_template, instantiate_decl,
|
||||
tsubst_initializer_list, tsubst_enum,
|
||||
get_mostly_instantiated_function_type,
|
||||
invalid_nontype_parm_type_p): Likewise.
|
||||
|
@ -1021,7 +1029,7 @@
|
|||
2002-02-01 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/4872
|
||||
* decl.c (finish_function): Warn about a non-void function with
|
||||
* decl.c (finish_function): Warn about a non-void function with
|
||||
no return statement and no abnormal exit.
|
||||
* cp-tree.h (struct cp_language_function): Add returns_abnormally.
|
||||
(current_function_returns_abnormally): New macro.
|
||||
|
|
|
@ -7328,14 +7328,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:
|
||||
|
@ -8247,12 +8241,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))
|
||||
{
|
||||
|
@ -11351,9 +11339,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -385,7 +385,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.
|
||||
|
@ -495,8 +494,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
|
||||
|
@ -845,29 +843,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
|
||||
|
@ -919,6 +894,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.
|
||||
|
@ -968,6 +958,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
|
||||
|
@ -6170,12 +6180,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 <? j;}} instead.
|
||||
the smaller counter twice. The GNU C @code{typeof} extension allows you
|
||||
to write safe macros that avoid this kind of problem (@pxref{Typeof}).
|
||||
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 <? j;}}
|
||||
instead.
|
||||
|
||||
Since @code{<?} and @code{>?} are built into the compiler, they properly
|
||||
handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2002-10-09 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
PR c/7353
|
||||
* g++.dg/ext/typedef-init.C: New test.
|
||||
* gcc.dg/typedef-init.c: New test.
|
||||
|
||||
2002-10-06 Neil Booth <neil@daikokuya.co.uk>
|
||||
|
||||
* gcc.dg/cpp/_Pragma4.c: New test.
|
||||
|
|
Loading…
Reference in New Issue