From 793833d7a78bb624965885760593495e7079d705 Mon Sep 17 00:00:00 2001 From: kan Date: Mon, 10 Feb 2003 05:41:50 +0000 Subject: Gcc 3.2.2-release. --- contrib/gcc/cp/ChangeLog | 117 +++++++++++++++++++++++++++++++++++++++++++ contrib/gcc/cp/Make-lang.in | 83 +++++++++++++++--------------- contrib/gcc/cp/NEWS | 24 +++++++++ contrib/gcc/cp/cp-tree.h | 10 +++- contrib/gcc/cp/cvt.c | 2 + contrib/gcc/cp/decl.c | 12 +++-- contrib/gcc/cp/decl2.c | 73 +++++++++++++++++---------- contrib/gcc/cp/error.c | 28 ++++++++++- contrib/gcc/cp/except.c | 2 +- contrib/gcc/cp/init.c | 2 +- contrib/gcc/cp/operators.def | 9 ++-- contrib/gcc/cp/parse.y | 4 +- contrib/gcc/cp/pt.c | 52 ++++++++----------- contrib/gcc/cp/rtti.c | 12 +++++ contrib/gcc/cp/search.c | 66 +++++++++++++++++++++++- contrib/gcc/cp/semantics.c | 20 +++++--- contrib/gcc/cp/tree.c | 15 ++++-- contrib/gcc/cp/typeck.c | 16 ++++-- 18 files changed, 424 insertions(+), 123 deletions(-) (limited to 'contrib/gcc/cp') diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 5a611ae..2fd119a 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,120 @@ +2003-02-05 Release Manager + + * GCC 3.2.2 Released. + +2003-02-03 Mark Mitchell + + PR C++/7129 + * operators.def: Add ?=. + +2003-01-28 Christian Cornelssen + + * Make-lang.in (c++.install-common, c++.install-man) + (c++.uninstall): Prepend $(DESTDIR) to destination paths + in all (un)installation commands. + (c++.install-common): Rewrite $(LN) commands to support + DESTDIR with "ln" as well as with "ln -s". + +2003-01-22 Mark Mitchell + + PR c++/9328 + * error.c (dump_decl): For an OVERLOAD, just print the name of the + function; it doesn't make sense to try to print its type. + * semantics.c (finish_typeof): Issue errors about invalid uses. + +2003-01-21 Jeffrey D. Oldham + + PR c++/47 + * cp-tree.h (lookup_nested_field): Add declaration. + * decl.c (lookup_name_real): Call lookup_nested_field. + * search.c (lookup_nested_field): Add function. + +2002-12-26 Nathan Sidwell + + PR c++/8503 + Remove DR 295 implementation. + * pt.c (check_cv_quals_for_unify): Disable function & method cases. + * tree.c (cp_build_qualified_type_real): Likewise. Don't warn + about ignoring volatile qualifiers. + +2002-12-18 Kriang Lerdsuwanakij + + * parse.y (bad_parm): Add missing argument to error function call. + +2002-12-18 Kriang Lerdsuwanakij + + PR c++/8442 + * decl2.c (handle_class_head): Verify if the looked up name is a + type or template. + * pt.c (convert_template_argument): Fix type or template template + parameter decision logic. + +2002-12-13 Joe Buck + + * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for + anonymous structs. + +2002-12-13 Gabriel Dos Reis + + PR C++/8031 + * cvt.c (convert_to_pointer_force): Don't try comparing against + erronous type. + +2002-12-10 Mark Mitchell + + PR c++/8372 + * pt.c (tsubst_copy): Handle destructor names more correctly. + +2002-12-05 Kaveh R. Ghazi + + * error.c (dump_expr): Fix format specifier warning. + +2002-12-04 Gabriel Dos Reis + + PR C++/8799 + * error.c (dump_expr): Don't ever try to dump a non-existent + expression. + +2002-12-02 Mark Mitchell + + PR c++/8615 + * error.c (dump_expr): Handle character constants with + TREE_OVERFLOW set. + +2002-12-01 Mark Mitchell + + PR c++/5919 + * pt.c (unify): Use variably_modified_type_p to test validity of + template argument types. + +2002-12-01 Mark Mitchell + + PR c++/8727 + * cp-tree.h (lang_type_class): Add typeinfo_var. + (CLASSTYPE_TYPEINFO_VAR): New macro. + * rtti.c (get_tinfo_decl): Use it. + + PR c++/8663 + * init.c (expand_member_init): Always get the main variant of a + base class. + +2002-12-01 Mark Mitchell + + PR c++/8332 + PR c++/8493 + * decl.c (cxx_init_decl_processing): Use size_type_node, not + c_size_type_node. + * decl2.c (coerce_new_type): Likewise. + * except.c (do_allocate_exception): Likewise. + * typeck.c (c_sizeof): Likewise. + (c_sizeof_nowarn): Likewise. + +2002-11-30 Mark Mitchell + + PR c++/8214 + * typeck.c (convert_for_assignment): Do not use + decl_constant_value on the operand. + 2002-11-19 Release Manager * GCC 3.2.1 Released. diff --git a/contrib/gcc/cp/Make-lang.in b/contrib/gcc/cp/Make-lang.in index df2de35..aef2d35 100644 --- a/contrib/gcc/cp/Make-lang.in +++ b/contrib/gcc/cp/Make-lang.in @@ -155,37 +155,42 @@ c++.install-normal: c++.install-common: installdirs -if [ -f cc1plus$(exeext) ] ; then \ if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g++-cross$(exeext) $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - chmod a+x $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - rm -f $(bindir)/$(CXX_CROSS_NAME)$(exeext); \ - $(LN) $(bindir)/$(GXX_CROSS_NAME)$(exeext) $(bindir)/$(CXX_CROSS_NAME)$(exeext); \ - if [ -d $(gcc_tooldir)/bin/. ] ; then \ - rm -f $(gcc_tooldir)/bin/g++$(exeext); \ - $(INSTALL_PROGRAM) g++-cross$(exeext) $(gcc_tooldir)/bin/g++$(exeext); \ - rm -f $(gcc_tooldir)/bin/c++$(exeext); \ - $(LN) $(gcc_tooldir)/bin/g++$(exeext) $(gcc_tooldir)/bin/c++$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \ + $(INSTALL_PROGRAM) g++-cross$(exeext) $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \ + chmod a+x $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(CXX_CROSS_NAME)$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GXX_CROSS_NAME)$(exeext) $(CXX_CROSS_NAME)$(exeext) ); \ + if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \ + rm -f $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \ + $(INSTALL_PROGRAM) g++-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \ + rm -f $(DESTDIR)$(gcc_tooldir)/bin/c++$(exeext); \ + ( cd $(DESTDIR)$(gcc_tooldir)/bin && \ + $(LN) g++$(exeext) c++$(exeext) ); \ else true; fi; \ else \ - rm -f $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g++$(exeext) $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - chmod a+x $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - rm -f $(bindir)/$(CXX_INSTALL_NAME)$(exeext); \ - $(LN) $(bindir)/$(GXX_INSTALL_NAME)$(exeext) $(bindir)/$(CXX_INSTALL_NAME)$(exeext); \ - rm -f $(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \ - $(LN) $(bindir)/$(GXX_INSTALL_NAME)$(exeext) $(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \ - rm -f $(bindir)/$(CXX_TARGET_INSTALL_NAME)$(exeext); \ - $(LN) $(bindir)/$(CXX_INSTALL_NAME)$(exeext) $(bindir)/$(CXX_TARGET_INSTALL_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) g++$(exeext) $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ + chmod a+x $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GXX_INSTALL_NAME)$(exeext) $(CXX_INSTALL_NAME)$(exeext) ); \ + rm -f $(DESTDIR)$(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GXX_INSTALL_NAME)$(exeext) $(GXX_TARGET_INSTALL_NAME)$(exeext) ); \ + rm -f $(DESTDIR)$(bindir)/$(CXX_TARGET_INSTALL_NAME)$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(CXX_INSTALL_NAME)$(exeext) $(CXX_TARGET_INSTALL_NAME)$(exeext) ); \ fi ; \ if [ x$(DEMANGLER_PROG) != x ] && [ -x "$(DEMANGLER_PROG)" ]; then \ if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - chmod a+x $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ + $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ + chmod a+x $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ else \ - rm -f $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - chmod a+x $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ + chmod a+x $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ fi ; \ fi ; \ fi @@ -195,25 +200,25 @@ c++.install-info: c++.install-man: installdirs $(srcdir)/cp/g++.1 -if [ -f cc1plus$(exeext) ] ; then \ if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ - chmod a-x $(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ + rm -f $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ + $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ + chmod a-x $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \ else \ - rm -f $(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ - chmod a-x $(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ + rm -f $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ + $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ + chmod a-x $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \ fi; \ else true; fi c++.uninstall: - -rm -rf $(bindir)/$(CXX_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(CXX_CROSS_NAME)$(exeext) - -rm -rf $(bindir)/$(GXX_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext) - -rm -rf $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext) - -rm -rf $(man1dir)/$(GXX_INSTALL_NAME)$(man1ext) - -rm -rf $(man1dir)/$(GXX_CROSS_NAME)$(man1ext) + -rm -rf $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(CXX_CROSS_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext) + -rm -rf $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext) # # Clean hooks: # A lot of the ancillary files are deleted by the main makefile. diff --git a/contrib/gcc/cp/NEWS b/contrib/gcc/cp/NEWS index caee3fb..97d4cd8 100644 --- a/contrib/gcc/cp/NEWS +++ b/contrib/gcc/cp/NEWS @@ -1,3 +1,27 @@ +*** Changes in GCC 3.2.2: + +* G++ no longer allows in-class initializations of static data members + that do not have arithmetic or enumeration type. For example: + + struct S { + static const char* const p = "abc"; + }; + + is no longer accepted. + + Use the standards-conformant form: + + struct S { + static const char* const p; + }; + + const char* const S::p = "abc"; + + instead. + + (ISO C++ is even stricter; it does not allow in-class + initializations of floating-point types.) + *** Changes in GCC 3.1: * -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index 9e8199f..a2c0db1 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -1,6 +1,6 @@ /* Definitions for C++ parsing and type checking. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -1266,6 +1266,7 @@ struct lang_type tree primary_base; tree vfields; + tree typeinfo_var; tree vbases; tree tags; tree size; @@ -1686,6 +1687,12 @@ struct lang_type /* Used by various search routines. */ #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) +/* The std::type_info variable representing this class, or NULL if no + such variable has been created. This field is only set for the + TYPE_MAIN_VARIANT of the class. */ +#define CLASSTYPE_TYPEINFO_VAR(NODE) \ + (TYPE_LANG_SPECIFIC (NODE)->typeinfo_var) + /* Accessor macros for the vfield slots in structures. */ /* The virtual function pointer fields that this type contains. For a @@ -4055,6 +4062,7 @@ extern tree get_dynamic_cast_base_type PARAMS ((tree, tree)); extern void type_access_control PARAMS ((tree, tree)); extern int accessible_p PARAMS ((tree, tree)); extern tree lookup_field PARAMS ((tree, tree, int, int)); +extern tree lookup_nested_field PARAMS ((tree, int)); extern int lookup_fnfields_1 PARAMS ((tree, tree)); extern tree lookup_fnfields PARAMS ((tree, tree, int)); extern tree lookup_member PARAMS ((tree, tree, int, int)); diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 5e6c92c..1603a2a 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -313,6 +313,8 @@ convert_to_pointer_force (type, expr) if (binfo) { expr = build_base_path (code, expr, binfo, 0); + if (expr == error_mark_node) + return error_mark_node; /* Add any qualifier conversions. */ if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), TREE_TYPE (type))) diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 06b081c..5c891a5 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -6173,6 +6173,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) } } + /* The name might be from an enclosing class of the current scope. */ + if (!val && !nonclass && current_class_type) + val = qualify_lookup (lookup_nested_field (name, !yylex), flags); + /* Now lookup in namespace scopes. */ if (!val || val_is_implicit_typename) { @@ -6659,7 +6663,7 @@ cxx_init_decl_processing () ptr_ftype_sizetype = build_function_type (ptr_type_node, tree_cons (NULL_TREE, - c_size_type_node, + size_type_node, void_list_node)); newtype = build_exception_variant (ptr_ftype_sizetype, add_exception_specifier @@ -9402,10 +9406,10 @@ check_static_variable_definition (decl, type) the definition, but not both. If it appears in the class, the member is a member constant. The file-scope definition is always required. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE) + if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE) { error ("invalid in-class initialization of static data member of non-integral type `%T'", - type); + type); /* If we just return the declaration, crashes will sometimes occur. We therefore return void_type_node, as if this was a friend declaration, to cause callers to completely ignore diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 730bbfb..1dbaaf4 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1583,30 +1583,32 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) else init = digest_init (TREE_TYPE (value), init, (tree *)0); } - - if (TREE_CODE (init) == CONST_DECL) - init = DECL_INITIAL (init); - else if (TREE_READONLY_DECL_P (init)) - init = decl_constant_value (init); - else if (TREE_CODE (init) == CONSTRUCTOR) - init = digest_init (TREE_TYPE (value), init, (tree *)0); - if (init == error_mark_node) - /* We must make this look different than `error_mark_node' - because `decl_const_value' would mis-interpret it - as only meaning that this VAR_DECL is defined. */ - init = build1 (NOP_EXPR, TREE_TYPE (value), init); - else if (processing_template_decl) - ; - else if (! TREE_CONSTANT (init)) + + if (!processing_template_decl) { - /* We can allow references to things that are effectively - static, since references are initialized with the address. */ - if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE - || (TREE_STATIC (init) == 0 - && (!DECL_P (init) || DECL_EXTERNAL (init) == 0))) + if (TREE_CODE (init) == CONST_DECL) + init = DECL_INITIAL (init); + else if (TREE_READONLY_DECL_P (init)) + init = decl_constant_value (init); + else if (TREE_CODE (init) == CONSTRUCTOR) + init = digest_init (TREE_TYPE (value), init, (tree *)0); + if (init == error_mark_node) + /* We must make this look different than `error_mark_node' + because `decl_const_value' would mis-interpret it + as only meaning that this VAR_DECL is defined. */ + init = build1 (NOP_EXPR, TREE_TYPE (value), init); + else if (! TREE_CONSTANT (init)) { - error ("field initializer is not constant"); - init = error_mark_node; + /* We can allow references to things that are effectively + static, since references are initialized with the + address. */ + if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE + || (TREE_STATIC (init) == 0 + && (!DECL_P (init) || DECL_EXTERNAL (init) == 0))) + { + error ("field initializer is not constant"); + init = error_mark_node; + } } } } @@ -2062,17 +2064,17 @@ coerce_new_type (type) e = 1, error ("`operator new' must return type `%T'", ptr_type_node); if (!args || args == void_list_node - || !same_type_p (TREE_VALUE (args), c_size_type_node)) + || !same_type_p (TREE_VALUE (args), size_type_node)) { e = 2; if (args && args != void_list_node) args = TREE_CHAIN (args); - pedwarn ("`operator new' takes type `size_t' (`%T') as first parameter", c_size_type_node); + pedwarn ("`operator new' takes type `size_t' (`%T') as first parameter", size_type_node); } switch (e) { case 2: - args = tree_cons (NULL_TREE, c_size_type_node, args); + args = tree_cons (NULL_TREE, size_type_node, args); /* FALLTHROUGH */ case 1: type = build_exception_variant @@ -5239,6 +5241,7 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) int *new_type_p; { tree decl = NULL_TREE; + tree type; tree current = current_scope (); bool xrefd_p = false; @@ -5287,12 +5290,28 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) xrefd_p = true; } - if (!TYPE_BINFO (TREE_TYPE (decl))) + type = TREE_TYPE (decl); + + if (!TYPE_BINFO (type)) { error ("`%T' is not a class or union type", decl); return error_mark_node; } - + + /* When `A' is a template class, using `class A' without template + argument is invalid unless + - we are inside the scope of the template class `A' or one of its + specialization. + - we are declaring the template class `A' itself. */ + if (TREE_CODE (type) == RECORD_TYPE + && CLASSTYPE_IS_TEMPLATE (type) + && processing_template_decl <= template_class_depth (current) + && ! is_base_of_enclosing_class (type, current_class_type)) + { + error ("template argument is required for `%T'", type); + return error_mark_node; + } + if (defn_p) { /* For a definition, we want to enter the containing scope diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 8a05558..a0217ae 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -935,6 +935,25 @@ dump_decl (t, flags) break; case OVERLOAD: + if (OVL_CHAIN (t)) + { + t = OVL_CURRENT (t); + if (DECL_CLASS_SCOPE_P (t)) + { + dump_type (DECL_CONTEXT (t), flags); + output_add_string (scratch_buffer, "::"); + } + else if (DECL_CONTEXT (t)) + { + dump_decl (DECL_CONTEXT (t), flags); + output_add_string (scratch_buffer, "::"); + } + dump_decl (DECL_NAME (t), flags); + break; + } + + /* If there's only one function, just treat it like an ordinary + FUNCTION_DECL. */ t = OVL_CURRENT (t); /* Fall through. */ @@ -1424,6 +1443,9 @@ dump_expr (t, flags) tree t; int flags; { + if (t == 0) + return; + switch (TREE_CODE (t)) { case VAR_DECL: @@ -1473,7 +1495,11 @@ dump_expr (t, flags) else if (type == char_type_node) { output_add_character (scratch_buffer, '\''); - dump_char (tree_low_cst (t, 0)); + if (host_integerp (t, TREE_UNSIGNED (type))) + dump_char (tree_low_cst (t, TREE_UNSIGNED (type))); + else + output_printf (scratch_buffer, "\\x%x", + (unsigned int) TREE_INT_CST_LOW (t)); output_add_character (scratch_buffer, '\''); } else diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c index 3f3cdcf..5de9f4c 100644 --- a/contrib/gcc/cp/except.c +++ b/contrib/gcc/cp/except.c @@ -508,7 +508,7 @@ do_allocate_exception (type) else { /* Declare void *__cxa_allocate_exception(size_t). */ - tree tmp = tree_cons (NULL_TREE, c_size_type_node, void_list_node); + tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node); fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp)); } diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index df63e67..1e08908 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -1062,7 +1062,7 @@ expand_member_init (exp, name, init) } else if (TYPE_P (name)) { - basetype = name; + basetype = TYPE_MAIN_VARIANT (name); name = TYPE_NAME (name); } else if (TREE_CODE (name) == TYPE_DECL) diff --git a/contrib/gcc/cp/operators.def b/contrib/gcc/cp/operators.def index 8504380..05a5a39 100644 --- a/contrib/gcc/cp/operators.def +++ b/contrib/gcc/cp/operators.def @@ -5,7 +5,7 @@ non-overloadable operators (like the `?:' ternary operator). Writtey by Mark Mitchell - Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU CC. @@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */ assignment operators, the same tree-codes are reused; i.e., `operator +' will also have PLUS_EXPR as its CODE. - NEW_MANGLING + MANGLING The mangling prefix for the operator, as a C string, and as mangled under the new ABI. For `operator +', for example, this @@ -127,7 +127,7 @@ DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2) DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2) DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2) DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2) -/* These are extensions. */ +/* These operators are GNU extensions. */ DEF_SIMPLE_OPERATOR ("?", MAX_EXPR, "v23max", 2) /* This one is needed for mangling. */ @@ -145,6 +145,9 @@ DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", 2) DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", 2) DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", 2) DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", 2) +/* These operators are GNU extensions. */ +DEF_ASSN_OPERATOR ("?=", MAX_EXPR, "v23maX", 2); /* Ternary operators. */ DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3) diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 5328ed3..e929ebe 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -2521,6 +2521,8 @@ class_head_defn: current_aggr = $1; $$.t = TYPE_MAIN_DECL (xref_tag ($1, make_anon_name (), 0)); $$.new_type_flag = 0; + CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($$.t)) + = $1 == class_type_node; yyungetc ('{', 1); } ; @@ -3823,7 +3825,7 @@ bad_parm: { if (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM || TREE_CODE (TREE_OPERAND ($$, 0)) == BOUND_TEMPLATE_TEMPLATE_PARM) - error ("`%E' is not a type, use `typename %E' to make it one", $$); + error ("`%E' is not a type, use `typename %E' to make it one", $$, $$); else error ("no type `%D' in `%T'", TREE_OPERAND ($$, 1), TREE_OPERAND ($$, 0)); } diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index b8e9545..b751ad4 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -3303,17 +3303,12 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); - else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg))) - { - if (is_base_of_enclosing_class (arg, current_class_type)) - /* This is a template name used within the scope of the - template. It could be the template, or it could be the - instantiation. Choose whichever makes sense. */ - is_tmpl_type = requires_tmpl_type; - else - is_tmpl_type = 1; - } + else if (CLASSTYPE_IS_TEMPLATE (arg) + && is_base_of_enclosing_class (arg, current_class_type)) + /* This is a template name used within the scope of the + template. It could be the template, or it could be the + instantiation. Choose whichever makes sense. */ + is_tmpl_type = requires_tmpl_type; else /* It is a non-template class, or a specialization of a template class, or a non-template member of a template class. */ @@ -7148,9 +7143,10 @@ tsubst_copy (t, args, complain, in_decl) { tree base = tsubst_copy (TREE_OPERAND (name, 0), args, complain, in_decl); - name = TREE_OPERAND (name, 1); - name = tsubst_copy (TREE_OPERAND (name, 0), args, - complain, in_decl); + name = TREE_OPERAND (TREE_OPERAND (name, 1), 0); + if (TREE_CODE (name) == TYPE_DECL) + name = TREE_TYPE (name); + name = tsubst_copy (name, args, complain, in_decl); name = build1 (BIT_NOT_EXPR, NULL_TREE, name); name = build_nt (SCOPE_REF, base, name); } @@ -8562,9 +8558,7 @@ check_cv_quals_for_unify (strict, arg, parm) { /* If the cvr quals of parm will not unify with ARG, they'll be ignored in instantiation, so we have to do the same here. */ - if (TREE_CODE (arg) == REFERENCE_TYPE - || TREE_CODE (arg) == FUNCTION_TYPE - || TREE_CODE (arg) == METHOD_TYPE) + if (TREE_CODE (arg) == REFERENCE_TYPE) parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); if (!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM) @@ -8789,21 +8783,17 @@ unify (tparms, targs, parm, arg, strict) return 0; else if (targ) return 1; - } - /* Make sure that ARG is not a variable-sized array. (Note that - were talking about variable-sized arrays (like `int[n]'), - rather than arrays of unknown size (like `int[]').) We'll - get very confused by such a type since the bound of the array - will not be computable in an instantiation. Besides, such - types are not allowed in ISO C++, so we can do as we please - here. */ - if (TREE_CODE (arg) == ARRAY_TYPE - && !uses_template_parms (arg) - && TYPE_DOMAIN (arg) - && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (arg))) - != INTEGER_CST)) - return 1; + /* Make sure that ARG is not a variable-sized array. (Note + that were talking about variable-sized arrays (like + `int[n]'), rather than arrays of unknown size (like + `int[]').) We'll get very confused by such a type since + the bound of the array will not be computable in an + instantiation. Besides, such types are not allowed in + ISO C++, so we can do as we please here. */ + if (variably_modified_type_p (arg)) + return 1; + } TREE_VEC_ELT (targs, idx) = arg; return 0; diff --git a/contrib/gcc/cp/rtti.c b/contrib/gcc/cp/rtti.c index 39cb1c6..fbb37fe 100644 --- a/contrib/gcc/cp/rtti.c +++ b/contrib/gcc/cp/rtti.c @@ -327,6 +327,15 @@ get_tinfo_decl (type) type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); + /* For a class type, the variable is cached in the type node + itself. */ + if (CLASS_TYPE_P (type)) + { + d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)); + if (d) + return d; + } + name = mangle_typeinfo_for_type (type); d = IDENTIFIER_GLOBAL_VALUE (name); @@ -346,6 +355,9 @@ get_tinfo_decl (type) pushdecl_top_level (d); + if (CLASS_TYPE_P (type)) + CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; + /* Remember the type it is for. */ TREE_TYPE (name) = type; } diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 9821907..38f4634 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -1,7 +1,7 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002 Free Software Foundation, Inc. + 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -1513,6 +1513,70 @@ lookup_fnfields (xbasetype, name, protect) return rval; } +/* Try to find NAME inside a nested class. */ + +tree +lookup_nested_field (name, complain) + tree name; + int complain; +{ + register tree t; + + tree id = NULL_TREE; + if (TYPE_MAIN_DECL (current_class_type)) + { + /* Climb our way up the nested ladder, seeing if we're trying to + modify a field in an enclosing class. If so, we should only + be able to modify if it's static. */ + for (t = TYPE_MAIN_DECL (current_class_type); + t && DECL_CONTEXT (t); + t = TYPE_MAIN_DECL (DECL_CONTEXT (t))) + { + if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE) + break; + + /* N.B.: lookup_field will do the access checking for us */ + id = lookup_field (DECL_CONTEXT (t), name, complain, 0); + if (id == error_mark_node) + { + id = NULL_TREE; + continue; + } + + if (id != NULL_TREE) + { + if (TREE_CODE (id) == FIELD_DECL + && ! TREE_STATIC (id) + && TREE_TYPE (id) != error_mark_node) + { + if (complain) + { + /* At parse time, we don't want to give this error, since + we won't have enough state to make this kind of + decision properly. But there are times (e.g., with + enums in nested classes) when we do need to call + this fn at parse time. So, in those cases, we pass + complain as a 0 and just return a NULL_TREE. */ + error ("assignment to non-static member `%D' of enclosing class `%T'", + id, DECL_CONTEXT (t)); + /* Mark this for do_identifier(). It would otherwise + claim that the variable was undeclared. */ + TREE_TYPE (id) = error_mark_node; + } + else + { + id = NULL_TREE; + continue; + } + } + break; + } + } + } + + return id; +} + /* TYPE is a class type. Return the index of the fields within the method vector with name NAME, or -1 is no such field exists. */ diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index a484203..a6f9afb 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -2079,20 +2079,28 @@ tree finish_typeof (expr) tree expr; { + tree type; + if (processing_template_decl) { - tree t; + type = make_aggr_type (TYPEOF_TYPE); + TYPE_FIELDS (type) = expr; - t = make_aggr_type (TYPEOF_TYPE); - TYPE_FIELDS (t) = expr; - - return t; + return type; } if (TREE_CODE (expr) == OFFSET_REF) expr = resolve_offset_ref (expr); - return TREE_TYPE (expr); + type = TREE_TYPE (expr); + + if (!type || type == unknown_type_node) + { + error ("type of `%E' is unknown", expr); + return error_mark_node; + } + + return type; } /* Compute the value of the `sizeof' operator. */ diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index 65dca00..cdfa49c 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -536,6 +536,11 @@ cp_build_qualified_type_real (type, type_quals, complain) { tree result; int bad_quals = TYPE_UNQUALIFIED; + /* We keep bad function qualifiers separate, so that we can decide + whether to implement DR 295 or not. DR 295 break existing code, + unfortunately. Remove this variable to implement the defect + report. */ + int bad_func_quals = TYPE_UNQUALIFIED; if (type == error_mark_node) return type; @@ -551,6 +556,8 @@ cp_build_qualified_type_real (type, type_quals, complain) || TREE_CODE (type) == METHOD_TYPE)) { bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + if (TREE_CODE (type) != REFERENCE_TYPE) + bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } @@ -569,21 +576,23 @@ cp_build_qualified_type_real (type, type_quals, complain) /*OK*/; else if (!(complain & (tf_error | tf_ignore_bad_quals))) return error_mark_node; + else if (bad_func_quals && !(complain & tf_error)) + return error_mark_node; else { if (complain & tf_ignore_bad_quals) /* We're not going to warn about constifying things that can't be constified. */ bad_quals &= ~TYPE_QUAL_CONST; + bad_quals |= bad_func_quals; if (bad_quals) { tree bad_type = build_qualified_type (ptr_type_node, bad_quals); - if (!(complain & tf_ignore_bad_quals)) + if (!(complain & tf_ignore_bad_quals) + || bad_func_quals) error ("`%V' qualifiers cannot be applied to `%T'", bad_type, type); - else if (complain & tf_warning) - warning ("ignoring `%V' qualifiers on `%T'", bad_type, type); } } diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index b019d0a..82867eb 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -1544,7 +1544,7 @@ c_sizeof (type) TYPE_IS_SIZETYPE means that certain things (like overflow) will never happen. However, this node should really have type `size_t', which is just a typedef for an ordinary integer type. */ - size = fold (build1 (NOP_EXPR, c_size_type_node, size)); + size = fold (build1 (NOP_EXPR, size_type_node, size)); my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)), 20001021); return size; @@ -1613,7 +1613,7 @@ c_sizeof_nowarn (type) TYPE_IS_SIZETYPE means that certain things (like overflow) will never happen. However, this node should really have type `size_t', which is just a typedef for an ordinary integer type. */ - size = fold (build1 (NOP_EXPR, c_size_type_node, size)); + size = fold (build1 (NOP_EXPR, size_type_node, size)); my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)), 20001021); return size; @@ -6195,8 +6195,16 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) /* Simplify the RHS if possible. */ if (TREE_CODE (rhs) == CONST_DECL) rhs = DECL_INITIAL (rhs); - else if (coder != ARRAY_TYPE) - rhs = decl_constant_value (rhs); + + /* We do not use decl_constant_value here because of this case: + + const char* const s = "s"; + + The conversion rules for a string literal are more lax than for a + variable; in particular, a string literal can be converted to a + "char *" but the variable "s" cannot be converted in the same + way. If the conversion is allowed, the optimization should be + performed while creating the converted expression. */ /* [expr.ass] -- cgit v1.1