summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog240
-rw-r--r--gcc/cp/Make-lang.in8
-rw-r--r--gcc/cp/call.c18
-rw-r--r--gcc/cp/class.c116
-rw-r--r--gcc/cp/cp-gimplify.c243
-rw-r--r--gcc/cp/cp-tree.h23
-rw-r--r--gcc/cp/decl.c180
-rw-r--r--gcc/cp/decl2.c54
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/except.c45
-rw-r--r--gcc/cp/init.c24
-rw-r--r--gcc/cp/lex.c11
-rw-r--r--gcc/cp/mangle.c5
-rw-r--r--gcc/cp/method.c1
-rw-r--r--gcc/cp/name-lookup.c15
-rw-r--r--gcc/cp/optimize.c28
-rw-r--r--gcc/cp/parser.c56
-rw-r--r--gcc/cp/pt.c19
-rw-r--r--gcc/cp/search.c14
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/cp/typeck.c68
-rw-r--r--gcc/cp/typeck2.c2
22 files changed, 849 insertions, 326 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index da6a3773dcd..bbb23ee1976 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,243 @@
+2008-07-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/36943
+ * decl.c (reshape_init_r): Allow C++0x initializer lists.
+
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_if_stmt): Set location on newly created
+ COND_EXPR.
+
+ 2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (finish_function): Call gimple_body after cp_genericize.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * optimize.c: Include gimple.h instead of tree-gimple.h.
+ * Make-lang.in (cp-gimplify.o): Depend on tree-iterator.h.
+ * cp-gimplify.c: Rename tree-gimple.h to gimple.h. Include
+ tree-iterator.h.
+
+ 2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE for the clone.
+
+ 2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Update comment.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Rename GENERIC_NEXT to
+ TREE_CHAIN.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (cxx_omp_clause_copy_ctor): Same.
+ (cxx_omp_clause_assign_op): Same.
+
+ 2008-05-28 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_omp_for): Add pre_p argument. Tuplify.
+ (cp_gimplify_expr): Adjust caller.
+
+ 2008-05-11 Doug Kwan <dougkwan@google.com>
+
+ * init.c (build_vec_delete): Add type conversion for argument
+ 0 of POINTER_PLUS_EXPR.
+
+ 2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * decl2 (File): Include "gimple.h"
+ (cp_write_global_declarations): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * Make-lang.in (cp/decl2.o): Add $(GIMPLE_H)
+
+ 2008-04-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00913.html
+
+ * optimize.c (maybe_clone_body): Re-enable call to
+ clone_body.
+ * cp-gimplify.c (cp_gimplify_omp_for): Mark disabled
+ code with call to gimple_unreachable.
+ (cp_genericize): Fix handling of clone bodies.
+
+ 2008-04-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00413.html
+
+ * optimize.c (maybe_clone_body): Re-enable.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * cp-gimplify.c (gimplify_for_stmt): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ (gimplify_must_not_throw_expr): Likewise.
+
+ 2008-02-04 Oleg Ryjkov <olegr@google.com>
+
+ * except.c: Include gimple.h
+ (cp_protect_cleanup_actions): Convert to tuples.
+ * Make-lang.in (cp/except.o): Add dependency on gimple.h
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Call tree_annotate_all_with_locus
+ instead of annotating each block manually.
+
+ 2007-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Tuplify.
+ (gimplify_for_stmt): Same.
+ (gimplify_switch_stmt): Same.
+ (cp_gimplify_expr): [FOR_STMT]: Do not call gimplify_for_stmt. Return
+ GS_OK.
+ [WHILE_STMT]: Return GS_OK.
+ [SWITCH_STMT]: Same.
+ [CONTINUE_STMT]: Same.
+ [BREAK_STMT]: Same.
+ (cp_genericize): Set gimple_body() of cloned functions when needed.
+
+ 2007-10-29 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c: Move build_gimple_eh_filter_tree here.
+ (cp_gimplify_init_expr): Convert to tuples.
+ (gimplify_must_not_throw_expr): Make function return a
+ gimplify_status and convert to tuples.
+
+ 2007-10-18 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c (genericize_try_block): Enable and do not call
+ gimplify_stmt.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_expr): Enable TRY_BLOCK, HANDLER, and EH_SPEC_BLOCK.
+
+ 2007-10-16 Aldy Hernandez <aldy@quesejoda.com>
+
+ * optimize.c (maybe_clone_body): Comment out call to clone_body.
+ * decl.c (finish_function): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * cp-tree.h (cp_gimplify_expr): Last 2 arguments are sequences.
+ * cp-gimplify.c (genericize_try_block): Comment out.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ (gimplify_cp_loop): Comment out calls to gimplify_stmt.
+ (gimplify_for_stmt): Comment out.
+ (gimplify_switch_stmt): Comment out call to gimplify_stmt.
+ (cp_gimplify_omp_for): Same.
+ (gimplify_must_not_throw_expr): Argument pre_p is a sequence.
+ Comment out call to gimplify_stmt and append_to_statement_list.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_init_expr): Arguments pre_p and post_p are sequences.
+ (cp_gimplify_expr): Same.
+ Comment out calls to genericize_*_block. Comment out call to
+ gimplify_for_stmt.
+
+2008-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/36944
+ * class.c (type_has_user_provided_default_constructor): Handle
+ default parameters.
+
+2008-07-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (push_library_fn): Add a parameter for the exceptions that
+ the function may throw.
+ (push_void_library_fn, push_throw_library_fn, expand_static_init):
+ Adjust.
+ (build_library_fn): Change to static.
+ * cp-tree.h: Adjust declarations.
+ * except.c (declare_nothrow_library_fn): New.
+ (do_get_exception_ptr, do_begin_catch, do_free_exception,
+ do_allocate_exception): Use the latter, adjust the declarations
+ (ie, add empty exception-specification), consistently with the
+ actual implementation in libsupc++.
+
+2008-07-25 Jan Hubicka <jh@suse.cz>
+
+ * typeck.c (inline_conversion): Remove.
+ (cp_build_function_call): Do not use inline_conversion.
+ * decl.c (duplicate_decls): Do not insist on inline being declared
+ early.
+ (start_cleanup_fn): Do not assume that INLINE flags prevent function
+ from being output. We now remove static functions always.
+ (finish_function): Do return warning on all static functions.
+ * call.c (build_over_call): Do not use inline_conversion.
+ * cp-tree.h (possibly_inlined_p): Declare.
+ (inline_conversion): Remove.
+ * pt.c (instantiate_decl): Use possibly_inlined_p predicate.
+ * decl2.c (cp_write_global_declarations): Likewise.
+ (mark_used): Likewise.
+ (possibly_inlined_p): New functions.
+
+2008-07-25 Jason Merrill <jason@redhat.com>
+
+ * class.c (type_has_user_provided_default_constructor): Handle
+ templates.
+
+2008-07-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (duplicate_decls): Update comment and unit-at-a-time.
+ (grogfndecl): Drop flag_inline_trees code.
+ * pt.c (instantiate_decl): Drop flag_iline_trees code.
+ * lex.c (cxx_init): Do not set unit-at-a-time.
+
+2008-07-23 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_unqualified_name): Avoid infinite recursion when
+ trying to mangle a decl with no name.
+
+ Implement defaulted/deleted functions as per N2346
+ * cp-tree.h (struct lang_decl_flags): Add defaulted_p bitfield.
+ (DECL_DELETED_FN): New macro.
+ (DECL_DEFAULTED_FN): New macro.
+ * class.c (user_provided_p): New fn.
+ (defaultable_fn_p): New fn.
+ (type_has_user_provided_constructor): New fn.
+ (type_has_user_provided_default_constructor): New fn.
+ (check_methods): A defaulted fn is still trivial.
+ (check_bases_and_members): Likewise.
+ * decl.c (grok_special_member_properties): Likewise.
+ (duplicate_decls): Complain about redeclaring a function as deleted.
+ (start_decl): initialized==2 means deleted.
+ (cp_finish_decl): Handle deleted/defaulted semantics.
+ * decl2.c (grokfield): Likewise.
+ (mark_used): Check DECL_DEFAULTED_FN instead of DECL_ARTIFICIAL.
+ Complain about using a deleted fn.
+ * init.c (build_value_init_1): Use type_has_user_provided_constructor.
+ (perform_member_init): Check for a user-provided default constructor
+ even if TYPE_NEEDS_CONSTRUCTING.
+ (build_new_1): Likewise.
+ * call.c (build_over_call): Don't call mark_used twice.
+ * method.c (implicitly_declare_fn): Set DECL_DEFAULTED_FN.
+ * search.c (check_final_overrider): Check for deleted mismatch.
+ * parser.c (cp_parser_init_declarator): Tell start_decl about =delete.
+ (cp_parser_pure_specifier): Handle =default and =delete.
+
+ * error.c (maybe_warn_cpp0x): Suggest -std=gnu++0x as well.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * typeck.c: All calls to pedwarn changed.
+ * decl.c: All calls to pedwarn changed.
+ * call.c: All calls to pedwarn changed.
+ * error.c: All calls to pedwarn changed.
+ * typeck2.c: All calls to pedwarn changed.
+ * pt.c: All calls to pedwarn changed.
+ * name-lookup.c: All calls to pedwarn changed.
+ * parser.c: All calls to pedwarn changed.
+
2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* call.c: Fix comment typos.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index c7877205f25..03963446251 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -239,7 +239,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H)
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \
- $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H)
+ $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H)
cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) toplev.h \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
@@ -280,17 +280,17 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
gt-cp-repo.h
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \
$(FLAGS_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
- $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H)
+ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H)
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
- insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(TREE_GIMPLE_H) \
+ insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
$(TARGET_H)
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
output.h $(TARGET_H)
cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h $(C_COMMON_H) \
- $(TM_H) coretypes.h pointer-set.h
+ $(TM_H) coretypes.h pointer-set.h tree-iterator.h
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h toplev.h \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 93ce4d8366d..cb07c82f1ab 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3404,8 +3404,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
calculated only once. */
if (!arg2)
{
- if (pedantic && (complain & tf_error))
- pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
+ if (complain & tf_error)
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids omitting the middle term of a ?: expression");
/* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
if (real_lvalue_p (arg1))
@@ -5089,6 +5090,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
int is_method = 0;
int nargs;
tree *argarray;
+ bool already_used = false;
/* In a template, there is no need to perform all of the work that
is normally done. We are only interested in the type of the call
@@ -5309,7 +5311,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* [class.copy]: the copy constructor is implicitly defined even if
the implementation elided its use. */
if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
- mark_used (fn);
+ {
+ mark_used (fn);
+ already_used = true;
+ }
/* If we're creating a temp and we already have one, don't create a
new one. If we're not creating a temp but we get one, use
@@ -5369,7 +5374,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return val;
}
- mark_used (fn);
+ if (!already_used)
+ mark_used (fn);
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
{
@@ -5394,8 +5400,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
TREE_TYPE (fn) = t;
}
- else if (DECL_INLINE (fn))
- fn = inline_conversion (fn);
else
fn = build_addr_func (fn);
@@ -6760,7 +6764,7 @@ tweak:
{
if (warn)
{
- warning (0,
+ pedwarn (0,
"ISO C++ says that these are ambiguous, even "
"though the worst conversion for the first is better than "
"the worst conversion for the second:");
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0c7a76c697a..f7e46a717aa 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3045,7 +3045,7 @@ check_field_decls (tree t, tree *access_decls,
/* Core issue 80: A nonstatic data member is required to have a
different name from the class iff the class has a
- user-defined constructor. */
+ user-declared constructor. */
if (constructor_name_p (DECL_NAME (x), t)
&& TYPE_HAS_USER_CONSTRUCTOR (t))
permerror ("field %q+#D with same name as class", x);
@@ -3767,8 +3767,8 @@ check_methods (tree t)
if (DECL_PURE_VIRTUAL_P (x))
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
}
- /* All user-declared destructors are non-trivial. */
- if (DECL_DESTRUCTOR_P (x))
+ /* All user-provided destructors are non-trivial. */
+ if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x))
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
}
}
@@ -4067,6 +4067,91 @@ type_has_user_nondefault_constructor (tree t)
return false;
}
+/* Returns true iff FN is a user-provided function, i.e. user-declared
+ and not defaulted at its first declaration. */
+
+static bool
+user_provided_p (tree fn)
+{
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ return true;
+ else
+ return (!DECL_ARTIFICIAL (fn)
+ && !(DECL_DEFAULTED_FN (fn)
+ && DECL_INITIALIZED_IN_CLASS_P (fn)));
+}
+
+/* Returns true iff class T has a user-provided constructor. */
+
+bool
+type_has_user_provided_constructor (tree t)
+{
+ tree fns;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ /* This can happen in error cases; avoid crashing. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ if (user_provided_p (OVL_CURRENT (fns)))
+ return true;
+
+ return false;
+}
+
+/* Returns true iff class T has a user-provided default constructor. */
+
+bool
+type_has_user_provided_default_constructor (tree t)
+{
+ tree fns, args;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && user_provided_p (fn))
+ {
+ args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ while (args && TREE_PURPOSE (args))
+ args = TREE_CHAIN (args);
+ if (!args || args == void_list_node)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Returns true if FN can be explicitly defaulted. */
+
+bool
+defaultable_fn_p (tree fn)
+{
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ if (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
+ == NULL_TREE)
+ return true;
+ else if (copy_fn_p (fn) > 0)
+ return true;
+ else
+ return false;
+ }
+ else if (DECL_DESTRUCTOR_P (fn))
+ return true;
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn))
+ return copy_fn_p (fn);
+ else
+ return false;
+}
+
/* Remove all zero-width bit-fields from T. */
static void
@@ -4158,6 +4243,8 @@ check_bases_and_members (tree t)
should take a non-const reference argument. */
int no_const_asn_ref;
tree access_decls;
+ bool saved_complex_asn_ref;
+ bool saved_nontrivial_dtor;
/* By default, we use const reference arguments and generate default
constructors. */
@@ -4171,6 +4258,12 @@ check_bases_and_members (tree t)
/* Check all the method declarations. */
check_methods (t);
+ /* Save the initial values of these flags which only indicate whether
+ or not the class has user-provided functions. As we analyze the
+ bases and members we can set these flags for other reasons. */
+ saved_complex_asn_ref = TYPE_HAS_COMPLEX_ASSIGN_REF (t);
+ saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
/* Check all the data member declarations. We cannot call
check_field_decls until we have called check_bases check_methods,
as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
@@ -4186,30 +4279,27 @@ check_bases_and_members (tree t)
/* Do some bookkeeping that will guide the generation of implicitly
declared member functions. */
- TYPE_HAS_COMPLEX_INIT_REF (t)
- |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t));
+ TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
/* We need to call a constructor for this class if it has a
- user-declared constructor, or if the default constructor is going
+ user-provided constructor, or if the default constructor is going
to initialize the vptr. (This is not an if-and-only-if;
TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
themselves need constructing.) */
TYPE_NEEDS_CONSTRUCTING (t)
- |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
+ |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
/* [dcl.init.aggr]
- An aggregate is an array or a class with no user-declared
+ An aggregate is an array or a class with no user-provided
constructors ... and no virtual functions.
Again, other conditions for being an aggregate are checked
elsewhere. */
CLASSTYPE_NON_AGGREGATE (t)
- |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t));
+ |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
CLASSTYPE_NON_POD_P (t)
|= (CLASSTYPE_NON_AGGREGATE (t)
- || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
- || TYPE_HAS_ASSIGN_REF (t));
- TYPE_HAS_COMPLEX_ASSIGN_REF (t)
- |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
+ || saved_nontrivial_dtor || saved_complex_asn_ref);
+ TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_DFLT (t)
|= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c6d64dfbb75..8dda74d3cbe 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "hashtab.h"
#include "pointer-set.h"
#include "flags.h"
@@ -62,20 +63,14 @@ begin_bc_block (enum bc_t bc)
If we saw a break (or continue) in the scope, append a LABEL_EXPR to
body. Otherwise, just forget the label. */
-static tree
-finish_bc_block (enum bc_t bc, tree label, tree body)
+static gimple_seq
+finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
{
gcc_assert (label == bc_label[bc]);
if (TREE_USED (label))
{
- tree t, sl = NULL;
-
- t = build1 (LABEL_EXPR, void_type_node, label);
-
- append_to_statement_list (body, &sl);
- append_to_statement_list (t, &sl);
- body = sl;
+ gimple_seq_add_stmt (&body, gimple_build_label (label));
}
bc_label[bc] = TREE_CHAIN (label);
@@ -83,11 +78,11 @@ finish_bc_block (enum bc_t bc, tree label, tree body)
return body;
}
-/* Build a GOTO_EXPR to represent a break or continue statement. BC
- indicates which. */
+/* Get the LABEL_EXPR to represent a break or continue statement
+ in the current block scope. BC indicates which. */
static tree
-build_bc_goto (enum bc_t bc)
+get_bc_label (enum bc_t bc)
{
tree label = bc_label[bc];
@@ -103,7 +98,7 @@ build_bc_goto (enum bc_t bc)
/* Mark the label used for finish_bc_block. */
TREE_USED (label) = 1;
- return build1 (GOTO_EXPR, void_type_node, label);
+ return label;
}
/* Genericize a TRY_BLOCK. */
@@ -114,13 +109,6 @@ genericize_try_block (tree *stmt_p)
tree body = TRY_STMTS (*stmt_p);
tree cleanup = TRY_HANDLERS (*stmt_p);
- gimplify_stmt (&body);
-
- if (CLEANUP_P (*stmt_p))
- /* A cleanup is an expression, so it doesn't need to be genericized. */;
- else
- gimplify_stmt (&cleanup);
-
*stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
}
@@ -132,12 +120,28 @@ genericize_catch_block (tree *stmt_p)
tree type = HANDLER_TYPE (*stmt_p);
tree body = HANDLER_BODY (*stmt_p);
- gimplify_stmt (&body);
-
/* FIXME should the caught type go in TREE_TYPE? */
*stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
}
+/* A terser interface for building a representation of an exception
+ specification. */
+
+static tree
+build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
+{
+ tree t;
+
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
+ append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
+
+ t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
+ append_to_statement_list (body, &TREE_OPERAND (t, 0));
+
+ return t;
+}
+
/* Genericize an EH_SPEC_BLOCK by converting it to a
TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
@@ -147,9 +151,8 @@ genericize_eh_spec_block (tree *stmt_p)
tree body = EH_SPEC_STMTS (*stmt_p);
tree allowed = EH_SPEC_RAISES (*stmt_p);
tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
- gimplify_stmt (&body);
- *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+ *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
}
/* Genericize an IF_STMT by turning it into a COND_EXPR. */
@@ -158,6 +161,7 @@ static void
gimplify_if_stmt (tree *stmt_p)
{
tree stmt, cond, then_, else_;
+ location_t locus = EXPR_LOCATION (*stmt_p);
stmt = *stmt_p;
cond = IF_COND (stmt);
@@ -175,6 +179,8 @@ gimplify_if_stmt (tree *stmt_p)
stmt = else_;
else
stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
+ if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
+ SET_EXPR_LOCATION (stmt, locus);
*stmt_p = stmt;
}
@@ -185,15 +191,20 @@ gimplify_if_stmt (tree *stmt_p)
evaluated before the loop body as in while and for loops, or after the
loop body as in do-while loops. */
-static tree
+static gimple_seq
gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
{
- tree top, entry, exit, cont_block, break_block, stmt_list, t;
+ gimple top, entry, stmt;
+ gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
+ tree cont_block, break_block;
location_t stmt_locus;
stmt_locus = input_location;
- stmt_list = NULL_TREE;
- entry = NULL_TREE;
+ stmt_list = NULL;
+ body_seq = NULL;
+ incr_seq = NULL;
+ exit_seq = NULL;
+ entry = NULL;
break_block = begin_bc_block (bc_break);
cont_block = begin_bc_block (bc_continue);
@@ -201,12 +212,12 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
/* If condition is zero don't generate a loop construct. */
if (cond && integer_zerop (cond))
{
- top = NULL_TREE;
- exit = NULL_TREE;
+ top = NULL;
if (cond_is_first)
{
- t = build_bc_goto (bc_break);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_break));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
else
@@ -215,44 +226,55 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
back through the main gimplifier to lower it. Given that we
have to gimplify the loop body NOW so that we can resolve
break/continue stmts, seems easier to just expand to gotos. */
- top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ top = gimple_build_label (create_artificial_label ());
/* If we have an exit condition, then we build an IF with gotos either
out of the loop, or to the top of it. If there's no exit condition,
then we just build a jump back to the top. */
- exit = build_and_jump (&LABEL_EXPR_LABEL (top));
if (cond && !integer_nonzerop (cond))
{
- t = build_bc_goto (bc_break);
- exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
- gimplify_stmt (&exit);
+ if (cond != error_mark_node)
+ {
+ gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
+ stmt = gimple_build_cond (NE_EXPR, cond,
+ build_int_cst (TREE_TYPE (cond), 0),
+ gimple_label_label (top),
+ get_bc_label (bc_break));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
if (cond_is_first)
{
if (incr)
{
- entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+ entry = gimple_build_label (create_artificial_label ());
+ stmt = gimple_build_goto (gimple_label_label (entry));
}
else
- t = build_bc_goto (bc_continue);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_continue));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
+ else
+ {
+ stmt = gimple_build_goto (gimple_label_label (top));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
}
- gimplify_stmt (&body);
- gimplify_stmt (&incr);
+ gimplify_stmt (&body, &body_seq);
+ gimplify_stmt (&incr, &incr_seq);
- body = finish_bc_block (bc_continue, cont_block, body);
+ body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
- append_to_statement_list (top, &stmt_list);
- append_to_statement_list (body, &stmt_list);
- append_to_statement_list (incr, &stmt_list);
- append_to_statement_list (entry, &stmt_list);
- append_to_statement_list (exit, &stmt_list);
+ gimple_seq_add_stmt (&stmt_list, top);
+ gimple_seq_add_seq (&stmt_list, body_seq);
+ gimple_seq_add_seq (&stmt_list, incr_seq);
+ gimple_seq_add_stmt (&stmt_list, entry);
+ gimple_seq_add_seq (&stmt_list, exit_seq);
- annotate_all_with_locus (&stmt_list, stmt_locus);
+ annotate_all_with_location (stmt_list, stmt_locus);
return finish_bc_block (bc_break, break_block, stmt_list);
}
@@ -261,45 +283,52 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
prequeue and hand off to gimplify_cp_loop. */
static void
-gimplify_for_stmt (tree *stmt_p, tree *pre_p)
+gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
if (FOR_INIT_STMT (stmt))
gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
- *stmt_p = gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
- FOR_EXPR (stmt), 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
+ FOR_EXPR (stmt), 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a WHILE_STMT node. */
static void
-gimplify_while_stmt (tree *stmt_p)
+gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
- NULL_TREE, 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
+ NULL_TREE, 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a DO_STMT node. */
static void
-gimplify_do_stmt (tree *stmt_p)
+gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
- NULL_TREE, 0);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
+ NULL_TREE, 0));
+ *stmt_p = NULL_TREE;
}
/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
static void
-gimplify_switch_stmt (tree *stmt_p)
+gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- tree break_block, body;
+ tree break_block, body, t;
location_t stmt_locus = input_location;
+ gimple_seq seq = NULL;
break_block = begin_bc_block (bc_break);
@@ -307,12 +336,14 @@ gimplify_switch_stmt (tree *stmt_p)
if (!body)
body = build_empty_stmt ();
- *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
- SWITCH_STMT_COND (stmt), body, NULL_TREE);
- SET_EXPR_LOCATION (*stmt_p, stmt_locus);
- gimplify_stmt (stmt_p);
+ t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
+ SWITCH_STMT_COND (stmt), body, NULL_TREE);
+ SET_EXPR_LOCATION (t, stmt_locus);
+ gimplify_and_add (t, &seq);
- *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p);
+ seq = finish_bc_block (bc_break, break_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
+ *stmt_p = NULL_TREE;
}
/* Hook into the middle of gimplifying an OMP_FOR node. This is required
@@ -321,10 +352,12 @@ gimplify_switch_stmt (tree *stmt_p)
regular gimplifier. */
static enum gimplify_status
-cp_gimplify_omp_for (tree *expr_p)
+cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tree for_stmt = *expr_p;
tree cont_block;
+ gimple stmt;
+ gimple_seq seq = NULL;
/* Protect ourselves from recursion. */
if (OMP_FOR_GIMPLIFYING_P (for_stmt))
@@ -336,10 +369,15 @@ cp_gimplify_omp_for (tree *expr_p)
statement expressions within the INIT, COND, or INCR expressions. */
cont_block = begin_bc_block (bc_continue);
- gimplify_stmt (expr_p);
+ gimplify_and_add (for_stmt, &seq);
+ stmt = gimple_seq_last_stmt (seq);
+ if (gimple_code (stmt) == GIMPLE_OMP_FOR)
+ gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
+ gimple_omp_body (stmt)));
+ else
+ seq = finish_bc_block (bc_continue, cont_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
- OMP_FOR_BODY (for_stmt)
- = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt));
OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
return GS_ALL_DONE;
@@ -383,7 +421,7 @@ gimplify_expr_stmt (tree *stmt_p)
/* Gimplify initialization from an AGGR_INIT_EXPR. */
static void
-cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree from = TREE_OPERAND (*expr_p, 1);
tree to = TREE_OPERAND (*expr_p, 0);
@@ -441,31 +479,31 @@ cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Gimplify a MUST_NOT_THROW_EXPR. */
-static void
-gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
+static enum gimplify_status
+gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
{
tree stmt = *expr_p;
tree temp = voidify_wrapper_expr (stmt, NULL);
tree body = TREE_OPERAND (stmt, 0);
- gimplify_stmt (&body);
-
- stmt = gimple_build_eh_filter (body, NULL_TREE,
- build_call_n (terminate_node, 0));
+ stmt = build_gimple_eh_filter_tree (body, NULL_TREE,
+ build_call_n (terminate_node, 0));
+ gimplify_and_add (stmt, pre_p);
if (temp)
{
- append_to_statement_list (stmt, pre_p);
*expr_p = temp;
+ return GS_OK;
}
- else
- *expr_p = stmt;
+
+ *expr_p = NULL;
+ return GS_ALL_DONE;
}
/* Do C++-specific gimplification. Args are as for gimplify_expr. */
int
-cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
int saved_stmts_are_full_exprs_p = 0;
enum tree_code code = TREE_CODE (*expr_p);
@@ -498,11 +536,10 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
break;
case MUST_NOT_THROW_EXPR:
- gimplify_must_not_throw_expr (expr_p, pre_p);
- ret = GS_OK;
+ ret = gimplify_must_not_throw_expr (expr_p, pre_p);
break;
- /* We used to do this for GIMPLE_MODIFY_STMT as well, but that's unsafe; the
+ /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
LHS of an assignment might also be involved in the RHS, as in bug
25979. */
case INIT_EXPR:
@@ -539,7 +576,7 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case USING_STMT:
/* Just ignore for now. Eventually we will want to pass this on to
the debugger. */
- *expr_p = build_empty_stmt ();
+ *expr_p = NULL;
ret = GS_ALL_DONE;
break;
@@ -550,35 +587,37 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case FOR_STMT:
gimplify_for_stmt (expr_p, pre_p);
- ret = GS_ALL_DONE;
+ ret = GS_OK;
break;
case WHILE_STMT:
- gimplify_while_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_while_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case DO_STMT:
- gimplify_do_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_do_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case SWITCH_STMT:
- gimplify_switch_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_switch_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case OMP_FOR:
- ret = cp_gimplify_omp_for (expr_p);
+ ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
case CONTINUE_STMT:
- *expr_p = build_bc_goto (bc_continue);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
case BREAK_STMT:
- *expr_p = build_bc_goto (bc_break);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
@@ -835,13 +874,13 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
p1 = create_tmp_var (TREE_TYPE (start1), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, start1);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
append_to_statement_list (t, &ret);
if (arg2)
{
p2 = create_tmp_var (TREE_TYPE (start2), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, start2);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
append_to_statement_list (t, &ret);
}
@@ -864,14 +903,14 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
append_to_statement_list (t, &ret);
if (arg2)
{
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
append_to_statement_list (t, &ret);
}
@@ -925,7 +964,7 @@ cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
@@ -941,7 +980,7 @@ cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6bc5d2d2782..f9a2af8bb01 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -534,7 +534,7 @@ enum cp_tree_node_structure_enum {
/* The resulting tree type. */
union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.generic)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("TS_CP_GENERIC"),
desc ("tree_node_structure (&%h)"))) generic;
@@ -1609,7 +1609,7 @@ struct lang_decl_flags GTY(())
unsigned repo_available_p : 1;
unsigned hidden_friend_p : 1;
unsigned threadprivate_p : 1;
- /* One unused bit. */
+ unsigned defaulted_p : 1;
union lang_decl_u {
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
@@ -2626,6 +2626,14 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define CP_DECL_THREADPRIVATE_P(DECL) \
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+/* Nonzero if DECL was declared with '= delete'. */
+#define DECL_DELETED_FN(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+
+/* Nonzero if DECL was declared with '= default'. */
+#define DECL_DEFAULTED_FN(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.defaulted_p)
+
/* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
@@ -4171,6 +4179,9 @@ extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
extern bool type_has_user_nondefault_constructor (tree);
+extern bool type_has_user_provided_constructor (tree);
+extern bool type_has_user_provided_default_constructor (tree);
+extern bool defaultable_fn_p (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
@@ -4214,10 +4225,9 @@ extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
extern tree check_for_out_of_scope_variable (tree);
-extern tree build_library_fn (tree, tree);
extern tree build_library_fn_ptr (const char *, tree);
extern tree build_cp_library_fn_ptr (const char *, tree);
-extern tree push_library_fn (tree, tree);
+extern tree push_library_fn (tree, tree, tree);
extern tree push_void_library_fn (tree, tree);
extern tree push_throw_library_fn (tree, tree);
extern tree check_tag_decl (cp_decl_specifier_seq *);
@@ -4323,6 +4333,7 @@ extern void mark_needed (tree);
extern bool decl_needed_p (tree);
extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
+extern bool possibly_inlined_p (tree);
/* in error.c */
extern void init_error (void);
@@ -4801,7 +4812,6 @@ extern int comp_cv_qual_signature (tree, tree);
extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
extern tree cxx_sizeof_nowarn (tree);
-extern tree inline_conversion (tree);
extern tree is_bitfield_expr_with_lowered_type (const_tree);
extern tree unlowered_expr_type (const_tree);
extern tree decay_conversion (tree);
@@ -4928,7 +4938,8 @@ extern void init_shadowed_var_for_decl (void);
extern tree cxx_staticp (tree);
/* in cp-gimplify.c */
-extern int cp_gimplify_expr (tree *, tree *, tree *);
+extern int cp_gimplify_expr (tree *, gimple_seq *,
+ gimple_seq *);
extern void cp_genericize (tree);
/* -- end of C++ */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e3043455257..2d9ccba3a5c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1551,14 +1551,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
olddecl);
}
}
-
- if (DECL_DECLARED_INLINE_P (newdecl)
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && TREE_ADDRESSABLE (olddecl) && warn_inline)
- {
- warning (0, "%q#D was used before it was declared inline", newdecl);
- warning (0, "%Jprevious non-inline declaration here", olddecl);
- }
}
}
@@ -1613,6 +1605,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
}
+
+ if (DECL_DELETED_FN (newdecl))
+ {
+ error ("deleted definition of %qD", newdecl);
+ error ("after previous declaration %q+D", olddecl);
+ }
}
/* Deal with C++: must preserve virtual function table size. */
@@ -1948,8 +1946,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
}
else if (new_defines_function && DECL_INITIAL (olddecl))
{
- /* C++ is always in in unit-at-a-time mode, so we never
- inline re-defined extern inline functions. */
+ /* Never inline re-defined extern inline functions.
+ FIXME: this could be better handled by keeping both
+ function as separate declarations. */
DECL_INLINE (newdecl) = 0;
DECL_UNINLINABLE (newdecl) = 1;
}
@@ -3591,7 +3590,7 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
We assume that such functions never throw; if this is incorrect,
callers should unset TREE_NOTHROW. */
-tree
+static tree
build_library_fn (tree name, tree type)
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
@@ -3630,12 +3629,18 @@ build_cp_library_fn_ptr (const char* name, tree type)
}
/* Like build_library_fn, but also pushes the function so that we will
- be able to find it via IDENTIFIER_GLOBAL_VALUE. */
+ be able to find it via IDENTIFIER_GLOBAL_VALUE. Also, the function
+ may throw exceptions listed in RAISES. */
tree
-push_library_fn (tree name, tree type)
+push_library_fn (tree name, tree type, tree raises)
{
- tree fn = build_library_fn (name, type);
+ tree fn;
+
+ if (raises)
+ type = build_exception_variant (type, raises);
+
+ fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
@@ -3660,7 +3665,7 @@ tree
push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
- return push_library_fn (name, type);
+ return push_library_fn (name, type, NULL_TREE);
}
/* Like push_library_fn, but also note that this function throws
@@ -3669,7 +3674,7 @@ push_void_library_fn (tree name, tree parmtypes)
tree
push_throw_library_fn (tree name, tree type)
{
- tree fn = push_library_fn (name, type);
+ tree fn = push_library_fn (name, type, NULL_TREE);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
@@ -3813,9 +3818,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
/* Anonymous unions are objects, so they can have specifiers. */;
SET_ANON_AGGR_TYPE_P (declared_type);
- if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
- && !in_system_header)
- pedwarn ("ISO C++ prohibits anonymous structs");
+ if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
+ pedwarn (OPT_pedantic, "ISO C++ prohibits anonymous structs");
}
else
@@ -3932,13 +3936,14 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
grokfield.) The DECL corresponding to the DECLARATOR is returned.
If an error occurs, the error_mark_node is returned instead.
- DECLSPECS are the decl-specifiers for the declaration. INITIALIZED
- is true if an explicit initializer is present, but false if this is
- a variable implicitly initialized via a default constructor.
- ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with
- this declaration. *PUSHED_SCOPE_P is set to the scope entered in
- this function, if any; if set, the caller is responsible for
- calling pop_scope. */
+ DECLSPECS are the decl-specifiers for the declaration. INITIALIZED is 1
+ if an explicit initializer is present, or 2 for an explicitly defaulted
+ function, or 3 for an explicitly deleted function, but 0 if this is a
+ variable implicitly initialized via a default constructor. ATTRIBUTES
+ and PREFIX_ATTRIBUTES are GNU attributes associated with this
+ declaration. *PUSHED_SCOPE_P is set to the scope entered in this
+ function, if any; if set, the caller is responsible for calling
+ pop_scope. */
tree
start_decl (const cp_declarator *declarator,
@@ -3992,12 +3997,15 @@ start_decl (const cp_declarator *declarator,
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- error ("typedef %qD is initialized (use __typeof__ instead)", decl);
+ error ("typedef %qD is initialized (use decltype instead)", decl);
return error_mark_node;
case FUNCTION_DECL:
- error ("function %q#D is initialized like a variable", decl);
- return error_mark_node;
+ if (initialized == 3)
+ /* We'll handle the rest of the semantics later, but we need to
+ set this now so it's visible to duplicate_decls. */
+ DECL_DELETED_FN (decl) = 1;
+ break;
default:
break;
@@ -4778,15 +4786,20 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
if (!CP_AGGREGATE_TYPE_P (type))
{
/* It is invalid to initialize a non-aggregate type with a
- brace-enclosed initializer.
+ brace-enclosed initializer before C++0x.
We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
a CONSTRUCTOR (with a record type). */
if (TREE_CODE (init) == CONSTRUCTOR
&& BRACE_ENCLOSED_INITIALIZER_P (init)) /* p7626.C */
{
- error ("braces around scalar initializer for type %qT", type);
- init = error_mark_node;
+ if (SCALAR_TYPE_P (type))
+ {
+ error ("braces around scalar initializer for type %qT", type);
+ init = error_mark_node;
+ }
+ else
+ maybe_warn_cpp0x ("extended initializer lists");
}
d->cur++;
@@ -5687,10 +5700,38 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
else
abstract_virtuals_error (decl, type);
- if (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_TYPE (decl) == error_mark_node)
+ if (TREE_TYPE (decl) == error_mark_node)
/* No initialization required. */
;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (init)
+ {
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ /* fixme check this is 1st decl */
+ DECL_DELETED_FN (decl) = 1;
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (!defaultable_fn_p (decl))
+ error ("%qD cannot be defaulted", decl);
+ else
+ {
+ /* An out-of-class default definition is defined at
+ the point where it is explicitly defaulted. */
+ DECL_DEFAULTED_FN (decl) = 1;
+ if (DECL_INITIAL (decl) == error_mark_node)
+ synthesize_method (decl);
+ }
+ }
+ else
+ error ("function %q#D is initialized like a variable", decl);
+ }
+ /* else no initialization required. */
+ }
else if (DECL_EXTERNAL (decl)
&& ! (DECL_LANG_SPECIFIC (decl)
&& DECL_NOT_REALLY_EXTERN (decl)))
@@ -5916,8 +5957,6 @@ start_cleanup_fn (void)
actually needed. It is unlikely that it will be inlined, since
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
- DECL_INLINE (fndecl) = 1;
- DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (use_cxa_atexit)
@@ -6141,9 +6180,10 @@ expand_static_init (tree decl, tree init)
void_list_node);
tree vfntype = build_function_type (void_type_node, argtypes);
acquire_fn = push_library_fn
- (acquire_fn, build_function_type (integer_type_node, argtypes));
- release_fn = push_library_fn (release_fn, vfntype);
- abort_fn = push_library_fn (abort_fn, vfntype);
+ (acquire_fn, build_function_type (integer_type_node, argtypes),
+ NULL_TREE);
+ release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
+ abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
}
else
{
@@ -6606,7 +6646,7 @@ grokfndecl (tree ctype,
/* We inline functions that are explicitly declared inline, or, when
the user explicitly asks us to, all functions. */
if (DECL_DECLARED_INLINE_P (decl)
- || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
+ || (!DECL_INLINE (decl) && funcdef_flag))
DECL_INLINE (decl) = 1;
DECL_EXTERNAL (decl) = 1;
@@ -7004,8 +7044,8 @@ check_static_variable_definition (tree decl, tree type)
error ("ISO C++ forbids in-class initialization of non-const "
"static member %qD",
decl);
- else if (pedantic && !INTEGRAL_TYPE_P (type))
- pedwarn ("ISO C++ forbids initialization of member constant "
+ else if (!INTEGRAL_TYPE_P (type))
+ pedwarn (OPT_pedantic, "ISO C++ forbids initialization of member constant "
"%qD of non-integral type %qT", decl, type);
return 0;
@@ -7082,12 +7122,12 @@ compute_array_index_type (tree name, tree size)
}
/* As an extension we allow zero-sized arrays. We always allow
them in system headers because glibc uses them. */
- else if (integer_zerop (size) && pedantic && !in_system_header)
+ else if (integer_zerop (size) && !in_system_header)
{
if (name)
- pedwarn ("ISO C++ forbids zero-size array %qD", name);
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
else
- pedwarn ("ISO C++ forbids zero-size array");
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array");
}
}
else if (TREE_CONSTANT (size))
@@ -7103,9 +7143,9 @@ compute_array_index_type (tree name, tree size)
else if (pedantic && warn_vla != 0)
{
if (name)
- pedwarn ("ISO C++ forbids variable length array %qD", name);
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
else
- pedwarn ("ISO C++ forbids variable length array");
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array");
}
else if (warn_vla > 0)
{
@@ -7362,7 +7402,7 @@ check_var_type (tree identifier, tree type)
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
BITFIELD for a field with specified width.
- INITIALIZED is 1 if the decl has an initializer.
+ INITIALIZED is as for start_decl.
ATTRLIST is a pointer to the list of attributes, which may be NULL
if there are none; *ATTRLIST may be modified if attributes from inside
@@ -7460,6 +7500,9 @@ grokdeclarator (const cp_declarator *declarator,
else if (decl_context == BITFIELD)
bitfield = 1, decl_context = FIELD;
+ if (initialized > 1)
+ funcdef_flag = true;
+
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
for (id_declarator = declarator;
@@ -7736,7 +7779,8 @@ grokdeclarator (const cp_declarator *declarator,
else if (! is_main)
permerror ("ISO C++ forbids declaration of %qs with no type", name);
else if (pedantic)
- pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids declaration of %qs with no type", name);
else
warning (OPT_Wreturn_type,
"ISO C++ forbids declaration of %qs with no type", name);
@@ -7791,7 +7835,8 @@ grokdeclarator (const cp_declarator *declarator,
ok = 1;
if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
{
- pedwarn ("long, short, signed or unsigned used invalidly for %qs",
+ pedwarn (OPT_pedantic,
+ "long, short, signed or unsigned used invalidly for %qs",
name);
if (flag_pedantic_errors)
ok = 0;
@@ -7896,7 +7941,8 @@ grokdeclarator (const cp_declarator *declarator,
if (pedantic)
{
tree bad_type = build_qualified_type (type, type_quals);
- pedwarn ("ignoring %qV qualifiers added to function type %qT",
+ pedwarn (OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
bad_type, type);
}
type_quals = TYPE_UNQUALIFIED;
@@ -9124,10 +9170,12 @@ grokdeclarator (const cp_declarator *declarator,
&& pedantic)
{
if (storage_class == sc_static)
- pedwarn ("%<static%> specified invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<static%> specified invalid for function %qs "
"declared out of global scope", name);
else
- pedwarn ("%<inline%> specifier invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<inline%> specifier invalid for function %qs "
"declared out of global scope", name);
}
@@ -9215,9 +9263,9 @@ grokdeclarator (const cp_declarator *declarator,
}
if (storage_class == sc_extern && pedantic)
{
- pedwarn ("cannot explicitly declare member %q#D to have "
- "extern linkage",
- decl);
+ pedwarn (OPT_pedantic,
+ "cannot explicitly declare member %q#D to have "
+ "extern linkage", decl);
storage_class = sc_none;
}
}
@@ -9666,6 +9714,8 @@ grok_special_member_properties (tree decl)
are no other parameters or else all other parameters have
default arguments. */
TYPE_HAS_INIT_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
if (ctor > 1)
TYPE_HAS_CONST_INIT_REF (class_type) = 1;
}
@@ -9687,6 +9737,8 @@ grok_special_member_properties (tree decl)
if (assop)
{
TYPE_HAS_ASSIGN_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
}
@@ -10104,8 +10156,8 @@ grok_op_properties (tree decl, bool complain)
if (operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR)
{
- if (pedantic)
- pedwarn ("%qD cannot have default arguments", decl);
+ pedwarn (OPT_pedantic, "%qD cannot have default arguments",
+ decl);
}
else
{
@@ -11961,13 +12013,15 @@ finish_function (int flags)
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
&& !DECL_NAME (DECL_RESULT (fndecl))
- /* Normally, with -Wreturn-type, flow will complain. Unless we're an
- inline function, as we might never be compiled separately. */
- && (DECL_INLINE (fndecl) || processing_template_decl)
+ && !TREE_NO_WARNING (fndecl)
/* Structor return values (if any) are set by the compiler. */
&& !DECL_CONSTRUCTOR_P (fndecl)
&& !DECL_DESTRUCTOR_P (fndecl))
- warning (OPT_Wreturn_type, "no return statement in function returning non-void");
+ {
+ warning (OPT_Wreturn_type,
+ "no return statement in function returning non-void");
+ TREE_NO_WARNING (fndecl) = 1;
+ }
/* Store the end of the function, so that we get good line number
info for the epilogue. */
@@ -11989,7 +12043,7 @@ finish_function (int flags)
f->extern_decl_map = NULL;
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ c_warn_unused_result (gimple_body (fndecl));
}
/* Clear out the bits we don't need. */
local_names = NULL;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f14f94d16b5..20b0826faf2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "tree-dump.h"
#include "intl.h"
+#include "gimple.h"
extern cpp_reader *parse_in;
@@ -821,7 +822,25 @@ grokfield (const cp_declarator *declarator,
{
/* Initializers for functions are rejected early in the parser.
If we get here, it must be a pure specifier for a method. */
- if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ DECL_DELETED_FN (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ DECL_INITIAL (value) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (!defaultable_fn_p (value))
+ error ("%qD cannot be defaulted", value);
+ else
+ {
+ DECL_DEFAULTED_FN (value) = 1;
+ DECL_INITIALIZED_IN_CLASS_P (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ DECL_INLINE (value) = 1;
+ }
+ }
+ else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
{
gcc_assert (error_operand_p (init) || integer_zerop (init));
DECL_PURE_VIRTUAL_P (value) = 1;
@@ -3404,7 +3423,7 @@ cp_write_global_declarations (void)
{
/* Does it need synthesizing? */
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
- && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl)))
+ && (! DECL_REALLY_EXTERN (decl) || possibly_inlined_p (decl)))
{
/* Even though we're already at the top-level, we push
there again. That way, when we pop back a few lines
@@ -3421,7 +3440,7 @@ cp_write_global_declarations (void)
reconsider = true;
}
- if (!DECL_SAVED_TREE (decl))
+ if (!gimple_body (decl))
continue;
/* We lie to the back end, pretending that some functions
@@ -3665,6 +3684,22 @@ check_default_args (tree x)
}
}
+/* Return true if function DECL can be inlined. This is used to force
+ instantiation of methods that might be interesting for inlining. */
+bool
+possibly_inlined_p (tree decl)
+{
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ if (DECL_UNINLINABLE (decl))
+ return false;
+ if (!optimize)
+ return DECL_DECLARED_INLINE_P (decl);
+ /* When optimizing, we might inline everything when flatten
+ attribute or heuristics inlining for size or autoinlining
+ is used. */
+ return true;
+}
+
/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
If DECL is a specialization or implicitly declared class member,
generate the actual definition. */
@@ -3739,7 +3774,7 @@ mark_used (tree decl)
/* Is it a synthesized method that needs to be synthesized? */
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
- && DECL_ARTIFICIAL (decl)
+ && DECL_DEFAULTED_FN (decl)
&& !DECL_THUNK_P (decl)
&& ! DECL_INITIAL (decl)
/* Kludge: don't synthesize for default args. Unfortunately this
@@ -3752,12 +3787,19 @@ mark_used (tree decl)
/* If we've already synthesized the method we don't need to
do the instantiation test below. */
}
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DELETED_FN (decl))
+ {
+ error ("deleted function %q+D", decl);
+ error ("used here");
+ }
else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_INLINE (DECL_TEMPLATE_RESULT
- (template_for_substitution (decl))))
+ && possibly_inlined_p
+ (DECL_TEMPLATE_RESULT (
+ template_for_substitution (decl))))
/* We need to instantiate static data members so that there
initializers are available in integral constant
expressions. */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 80aa6e962d2..ef26ad9114a 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2685,7 +2685,7 @@ maybe_warn_cpp0x (const char* str)
/* We really want to suppress this warning in system headers,
because libstdc++ uses variadic templates even when we aren't
in C++0x mode. */
- pedwarn ("%s only available with -std=c++0x", str);
+ pedwarn (0, "%s only available with -std=c++0x or -std=gnu++0x", str);
}
/* Warn about the use of variadic templates when appropriate. */
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 3070cda4d54..56a551212fe 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1,6 +1,7 @@
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
@@ -38,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-iterator.h"
#include "target.h"
+#include "gimple.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
@@ -52,7 +54,7 @@ static tree wrap_cleanups_r (tree *, int *, void *);
static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand (tree);
static int can_convert_eh (tree, tree);
-static tree cp_protect_cleanup_actions (void);
+static gimple cp_protect_cleanup_actions (void);
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
@@ -91,14 +93,14 @@ init_exception_processing (void)
/* Returns an expression to be executed if an unhandled exception is
propagated out of a cleanup region. */
-static tree
+static gimple
cp_protect_cleanup_actions (void)
{
/* [except.terminate]
When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */
- return build_call_n (terminate_node, 0);
+ return gimple_build_call (terminate_node, 0);
}
static tree
@@ -160,6 +162,21 @@ build_exc_ptr (void)
return build0 (EXC_PTR_EXPR, ptr_type_node);
}
+/* Declare a function NAME, returning RETURN_TYPE, taking a single
+ parameter PARM_TYPE, with an empty exception specification.
+
+ Note that the C++ ABI document does not have a throw-specifier on
+ the routines declared below via this function. The declarations
+ are consistent with the actual implementations in libsupc++. */
+
+static tree
+declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+{
+ tree tmp = tree_cons (NULL_TREE, parm_type, void_list_node);
+ return push_library_fn (name, build_function_type (return_type, tmp),
+ empty_except_spec);
+}
+
/* Build up a call to __cxa_get_exception_ptr so that we can build a
copy constructor for the thrown object. */
@@ -171,9 +188,8 @@ do_get_exception_ptr (void)
fn = get_identifier ("__cxa_get_exception_ptr");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void* __cxa_get_exception_ptr (void *). */
- tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
@@ -192,9 +208,8 @@ do_begin_catch (void)
fn = get_identifier ("__cxa_begin_catch");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void* __cxa_begin_catch (void *). */
- tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void* __cxa_begin_catch (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
@@ -543,9 +558,8 @@ do_allocate_exception (tree type)
fn = get_identifier ("__cxa_allocate_exception");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void *__cxa_allocate_exception(size_t). */
- tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void *__cxa_allocate_exception(size_t) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
}
return cp_build_function_call (fn,
@@ -565,9 +579,8 @@ do_free_exception (tree ptr)
fn = get_identifier ("__cxa_free_exception");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void __cxa_free_exception (void *). */
- fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
- void_list_node));
+ /* Declare void __cxa_free_exception (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 7319568b4b4..3deb85d432b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -346,7 +346,7 @@ build_value_init_1 (tree type, bool have_ctor)
if (CLASS_TYPE_P (type))
{
- if (TYPE_HAS_USER_CONSTRUCTOR (type) && !have_ctor)
+ if (type_has_user_provided_constructor (type) && !have_ctor)
return build_cplus_new
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
@@ -516,8 +516,17 @@ perform_member_init (tree member, tree init)
tf_warning_or_error));
}
else
- finish_expr_stmt (build_aggr_init (decl, init, 0,
- tf_warning_or_error));
+ {
+ if (CP_TYPE_CONST_P (type)
+ && init == NULL_TREE
+ && !type_has_user_provided_default_constructor (type))
+ /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
+ vtable; still give this diagnostic. */
+ permerror ("%Juninitialized member %qD with %<const%> type %qT",
+ current_function_decl, member, type);
+ finish_expr_stmt (build_aggr_init (decl, init, 0,
+ tf_warning_or_error));
+ }
}
else
{
@@ -1883,7 +1892,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
- if (CP_TYPE_CONST_P (elt_type) && !is_initialized)
+
+ if (CP_TYPE_CONST_P (elt_type) && !init
+ && !type_has_user_provided_default_constructor (elt_type))
{
if (complain & tf_error)
error ("uninitialized const in %<new%> of %q#T", elt_type);
@@ -3264,6 +3275,7 @@ build_vec_delete (tree base, tree maxindex,
{
/* Step back one from start of vector, and read dimension. */
tree cookie_addr;
+ tree size_ptr_type = build_pointer_type (sizetype);
if (TREE_SIDE_EFFECTS (base))
{
@@ -3273,8 +3285,8 @@ build_vec_delete (tree base, tree maxindex,
type = strip_array_types (TREE_TYPE (type));
cookie_addr = fold_build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (sizetype));
cookie_addr = build2 (POINTER_PLUS_EXPR,
- build_pointer_type (sizetype),
- base,
+ size_ptr_type,
+ fold_convert (size_ptr_type, base),
cookie_addr);
maxindex = cp_build_indirect_ref (cookie_addr, NULL, tf_warning_or_error);
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index ee2f2a80706..2c169d1bd76 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -247,17 +247,6 @@ cxx_init (void)
cxx_init_decl_processing ();
- /* The fact that G++ uses COMDAT for many entities (inline
- functions, template instantiations, virtual tables, etc.) mean
- that it is fundamentally unreliable to try to make decisions
- about whether or not to output a particular entity until the end
- of the compilation. However, the inliner requires that functions
- be provided to the back end if they are to be inlined.
- Therefore, we always use unit-at-a-time mode; in that mode, we
- can provide entities to the back end and it will decide what to
- emit based on what is actually needed. */
- flag_unit_at_a_time = 1;
-
if (c_common_init () == false)
{
input_location = saved_loc;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 1bc72b86a2d..0703d0a96f7 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1056,7 +1056,10 @@ write_unqualified_name (const tree decl)
else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
write_special_name_destructor (decl);
else if (DECL_NAME (decl) == NULL_TREE)
- write_source_name (DECL_ASSEMBLER_NAME (decl));
+ {
+ gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
+ write_source_name (DECL_ASSEMBLER_NAME (decl));
+ }
else if (DECL_CONV_FN_P (decl))
{
/* Conversion operator. Handle it right here.
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index bd63d0cba52..f3d23eba23d 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1108,6 +1108,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
DECL_IN_AGGR_P (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
+ DECL_DEFAULTED_FN (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_DECLARED_INLINE_P (fn) = 1;
DECL_INLINE (fn) = 1;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 477cfb367e8..9b456d54c57 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -724,10 +724,10 @@ pushdecl_maybe_friend (tree x, bool is_friend)
/* Don't do anything just yet. */;
else if (t == wchar_decl_node)
{
- if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
- pedwarn ("redeclaration of %<wchar_t%> as %qT",
+ if (! DECL_IN_SYSTEM_HEADER (x))
+ pedwarn (OPT_pedantic, "redeclaration of %<wchar_t%> as %qT",
TREE_TYPE (x));
-
+
/* Throw away the redeclaration. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
@@ -796,10 +796,11 @@ pushdecl_maybe_friend (tree x, bool is_friend)
x_exception_spec,
true))
{
- pedwarn ("declaration of %q#D with C language linkage", x);
- pedwarn ("conflicts with previous declaration %q+#D",
- previous);
- pedwarn ("due to different exception specifications");
+ pedwarn (0, "declaration of %q#D with C language linkage",
+ x);
+ pedwarn (0, "conflicts with previous declaration %q+#D",
+ previous);
+ pedwarn (0, "due to different exception specifications");
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
}
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index a91f8d5f564..ed43b435831 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -1,5 +1,5 @@
/* Perform optimizations on tree structure.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
/* Prototypes. */
@@ -72,35 +72,40 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
}
-/* FN is a function that has a complete body, and CLONE is a function whose
- body is to be set to a copy of FN, mapping argument declarations according
- to the ARG_MAP splay_tree. */
+
+/* FN is a function in High GIMPLE form that has a complete body and no
+ CFG. CLONE is a function whose body is to be set to a copy of FN,
+ mapping argument declarations according to the ARG_MAP splay_tree. */
static void
clone_body (tree clone, tree fn, void *arg_map)
{
copy_body_data id;
+ gimple_seq new_body;
+
+ /* FN must already be in GIMPLE form. */
+ gcc_assert (gimple_body (fn));
- /* Clone the body, as if we were making an inline call. But, remap the
- parameters in the callee to the parameters of caller. */
+ /* Clone the body, as if we were making an inline call. But, remap
+ the parameters in the callee to the parameters of caller. */
memset (&id, 0, sizeof (id));
id.src_fn = fn;
id.dst_fn = clone;
id.src_cfun = DECL_STRUCT_FUNCTION (fn);
- id.decl_map = (struct pointer_map_t *)arg_map;
+ id.decl_map = (struct pointer_map_t *) arg_map;
id.copy_decl = copy_decl_no_change;
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = insert_block;
+ id.transform_lang_insert_block = NULL;
/* We're not inside any EH region. */
id.eh_region = -1;
/* Actually copy the body. */
- append_to_statement_list_force (copy_generic_body (&id),
- &DECL_SAVED_TREE (clone));
+ new_body = remap_gimple_seq (gimple_body (fn), &id);
+ gimple_set_body (clone, new_body);
}
/* FN is a function that has a complete body. Clone the body as
@@ -228,6 +233,7 @@ maybe_clone_body (tree fn)
/* Now, expand this function into RTL, if appropriate. */
finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
+ DECL_SAVED_TREE (clone) = NULL;
expand_or_defer_fn (clone);
first = false;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 03606084258..15b66b03b95 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2162,7 +2162,8 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
error ("%H%<long long long%> is too long for GCC", &location);
else if (pedantic && !in_system_header && warn_long_long
&& cxx_dialect == cxx98)
- pedwarn ("%HISO C++ 1998 does not support %<long long%>",
+ pedwarn (OPT_Wlong_long,
+ "%HISO C++ 1998 does not support %<long long%>",
&location);
}
else if (count > 1)
@@ -3214,9 +3215,9 @@ cp_parser_primary_expression (cp_parser *parser,
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
/* Statement-expressions are not allowed by the standard. */
- if (pedantic)
- pedwarn ("%HISO C++ forbids braced-groups within expressions",
- &token->location);
+ pedwarn (OPT_pedantic,
+ "%HISO C++ forbids braced-groups within expressions",
+ &token->location);
/* And they're not allowed outside of a function-body; you
cannot, for example, write:
@@ -4545,8 +4546,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
/* Warn the user that a compound literal is not
allowed in standard C++. */
- if (pedantic)
- pedwarn ("ISO C++ forbids compound-literals");
+ pedwarn (OPT_pedantic, "ISO C++ forbids compound-literals");
/* For simplicity, we disallow compound literals in
constant-expressions. We could
allow compound literals of integer type, whose
@@ -7610,8 +7610,7 @@ cp_parser_jump_statement (cp_parser* parser)
if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
{
/* Issue a warning about this use of a GNU extension. */
- if (pedantic)
- pedwarn ("%HISO C++ forbids computed gotos", &token->location);
+ pedwarn (OPT_pedantic, "%HISO C++ forbids computed gotos", &token->location);
/* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */
@@ -7750,8 +7749,8 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
/* A declaration consisting of a single semicolon is
invalid. Allow it unless we're being pedantic. */
cp_lexer_consume_token (parser->lexer);
- if (pedantic && !in_system_header)
- pedwarn ("extra %<;%>");
+ if (!in_system_header)
+ pedwarn (OPT_pedantic, "extra %<;%>");
continue;
}
@@ -11734,8 +11733,8 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
/* If the next token is a `}', there is a trailing comma. */
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
{
- if (pedantic && !in_system_header)
- pedwarn ("comma at end of enumerator list");
+ if (!in_system_header)
+ pedwarn (OPT_pedantic, "comma at end of enumerator list");
break;
}
}
@@ -12379,7 +12378,7 @@ cp_parser_init_declarator (cp_parser* parser,
tree initializer;
tree decl = NULL_TREE;
tree scope;
- bool is_initialized;
+ int is_initialized;
/* Only valid if IS_INITIALIZED is true. In that case, CPP_EQ if
initialized with "= ..", CPP_OPEN_PAREN if initialized with
"(...)". */
@@ -12515,8 +12514,18 @@ cp_parser_init_declarator (cp_parser* parser,
|| token->type == CPP_OPEN_PAREN
|| token->type == CPP_OPEN_BRACE)
{
- is_initialized = true;
+ is_initialized = 1;
initialization_kind = token->type;
+
+ if (token->type == CPP_EQ
+ && function_declarator_p (declarator))
+ {
+ cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (t2->keyword == RID_DEFAULT)
+ is_initialized = 2;
+ else if (t2->keyword == RID_DELETE)
+ is_initialized = 3;
+ }
}
else
{
@@ -12528,7 +12537,7 @@ cp_parser_init_declarator (cp_parser* parser,
cp_parser_error (parser, "expected initializer");
return error_mark_node;
}
- is_initialized = false;
+ is_initialized = 0;
initialization_kind = CPP_EOF;
}
@@ -14369,8 +14378,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
{
/* Warn the user that they are using an extension. */
- if (pedantic)
- pedwarn ("ISO C++ does not allow designated initializers");
+ pedwarn (OPT_pedantic,
+ "ISO C++ does not allow designated initializers");
/* Consume the identifier. */
identifier = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `:'. */
@@ -15386,8 +15395,8 @@ cp_parser_member_declaration (cp_parser* parser)
if (!decl_specifiers.any_specifiers_p)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
- if (pedantic && !in_system_header_at (token->location))
- pedwarn ("%Hextra %<;%>", &token->location);
+ if (!in_system_header_at (token->location))
+ pedwarn (OPT_pedantic, "%Hextra %<;%>", &token->location);
}
else
{
@@ -15682,6 +15691,15 @@ cp_parser_pure_specifier (cp_parser* parser)
return error_mark_node;
/* Look for the `0' token. */
token = cp_lexer_consume_token (parser->lexer);
+
+ /* Accept = default or = delete in c++0x mode. */
+ if (token->keyword == RID_DEFAULT
+ || token->keyword == RID_DELETE)
+ {
+ maybe_warn_cpp0x ("defaulted and deleted functions");
+ return token->u.value;
+ }
+
/* c_lex_with_flags marks a single digit '0' with PURE_ZERO. */
if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c609bd0cc3a..b47ee5e6b3f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14610,8 +14610,9 @@ do_decl_instantiation (tree decl, tree storage)
;
else if (storage == ridpointers[(int) RID_EXTERN])
{
- if (pedantic && !in_system_header && (cxx_dialect == cxx98))
- pedwarn ("ISO C++ 1998 forbids the use of %<extern%> on explicit "
+ if (!in_system_header && (cxx_dialect == cxx98))
+ pedwarn (OPT_pedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on explicit "
"instantiations");
extern_p = 1;
}
@@ -14697,16 +14698,17 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
if (storage != NULL_TREE)
{
- if (pedantic && !in_system_header)
+ if (!in_system_header)
{
if (storage == ridpointers[(int) RID_EXTERN])
{
if (cxx_dialect == cxx98)
- pedwarn("ISO C++ 1998 forbids the use of %<extern%> on "
+ pedwarn(OPT_pedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on "
"explicit instantiations");
}
else
- pedwarn("ISO C++ forbids the use of %qE on explicit "
+ pedwarn(OPT_pedantic, "ISO C++ forbids the use of %qE on explicit "
"instantiations", storage);
}
@@ -15142,7 +15144,8 @@ instantiate_decl (tree d, int defer_ok,
if (external_p
/* ... but we instantiate inline functions so that we can inline
them and ... */
- && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+ && ! (TREE_CODE (d) == FUNCTION_DECL
+ && possibly_inlined_p (d))
/* ... we instantiate static data members whose values are
needed in integral constant expressions. */
&& ! (TREE_CODE (d) == VAR_DECL
@@ -15219,9 +15222,7 @@ instantiate_decl (tree d, int defer_ok,
/* Instantiate inline functions so that the inliner can do its
job, even though we'll not be emitting a copy of this
function. */
- if (!(TREE_CODE (d) == FUNCTION_DECL
- && flag_inline_trees
- && DECL_DECLARED_INLINE_P (d)))
+ if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d)))
goto out;
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index cee29240e9e..7fc040bc8c4 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1912,6 +1912,20 @@ check_final_overrider (tree overrider, tree basefn)
return 0;
}
+ if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
+ {
+ if (DECL_DELETED_FN (overrider))
+ {
+ error ("deleted function %q+D", overrider);
+ error ("overriding non-deleted function %q+D", basefn);
+ }
+ else
+ {
+ error ("non-deleted function %q+D", overrider);
+ error ("overriding deleted function %q+D", basefn);
+ }
+ return 0;
+ }
return 1;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ffa6493ced4..5ada42241fb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "vec.h"
#include "target.h"
+#include "gimple.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@@ -3201,6 +3202,8 @@ expand_or_defer_fn (tree fn)
return;
}
+ gcc_assert (gimple_body (fn));
+
/* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
cp_walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
simplify_aggr_init_exprs_r,
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 3468bd41a12..fcf52dc9db4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -511,9 +511,10 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
tree attributes;
tree result_type;
- if (pedantic && TYPE_PTRFN_P (t2) && (complain & tf_error))
- pedwarn ("ISO C++ forbids %s between pointer of type %<void *%> "
- "and pointer-to-function", location);
+ if (TYPE_PTRFN_P (t2) && (complain & tf_error))
+ pedwarn (OPT_pedantic, "ISO C++ forbids %s "
+ "between pointer of type %<void *%> and pointer-to-function",
+ location);
result_type
= cp_build_qualified_type (void_type_node,
(cp_type_quals (TREE_TYPE (t1))
@@ -1278,8 +1279,9 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
type = non_reference (type);
if (TREE_CODE (type) == METHOD_TYPE)
{
- if (complain && (pedantic || warn_pointer_arith))
- pedwarn ("invalid application of %qs to a member function",
+ if (complain)
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "invalid application of %qs to a member function",
operator_name_info[(int) op].name);
value = size_one_node;
}
@@ -1696,18 +1698,6 @@ perform_integral_promotions (tree expr)
return expr;
}
-/* Take the address of an inline function without setting TREE_ADDRESSABLE
- or TREE_USED. */
-
-tree
-inline_conversion (tree exp)
-{
- if (TREE_CODE (exp) == FUNCTION_DECL)
- exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
-
- return exp;
-}
-
/* Returns nonzero iff exp is a STRING_CST or the result of applying
decay_conversion to one. */
@@ -2596,8 +2586,8 @@ build_array_ref (tree array, tree idx)
return error_mark_node;
}
- if (pedantic && !lvalue_p (array))
- pedwarn ("ISO C++ forbids subscripting non-lvalue array");
+ if (!lvalue_p (array))
+ pedwarn (OPT_pedantic, "ISO C++ forbids subscripting non-lvalue array");
/* Note in C++ it is valid to subscript a `register' array, since
it is valid to take the address of something with that
@@ -2822,17 +2812,11 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
fndecl = function;
/* Convert anything with function type to a pointer-to-function. */
- if (pedantic && DECL_MAIN_P (function) && (complain & tf_error))
- pedwarn ("ISO C++ forbids calling %<::main%> from within program");
-
- /* Differs from default_conversion by not setting TREE_ADDRESSABLE
- (because calling an inline function does not mean the function
- needs to be separately compiled). */
+ if (DECL_MAIN_P (function) && (complain & tf_error))
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids calling %<::main%> from within program");
- if (DECL_INLINE (function))
- function = inline_conversion (function);
- else
- function = build_addr_func (function);
+ function = build_addr_func (function);
}
else
{
@@ -4101,15 +4085,12 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
if (!complete_type_or_else (target_type, NULL_TREE))
return error_mark_node;
- if (pedantic || warn_pointer_arith)
- {
- if (TREE_CODE (target_type) == VOID_TYPE)
- permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
- if (TREE_CODE (target_type) == FUNCTION_TYPE)
- permerror ("ISO C++ forbids using pointer to a function in subtraction");
- if (TREE_CODE (target_type) == METHOD_TYPE)
- permerror ("ISO C++ forbids using pointer to a method in subtraction");
- }
+ if (TREE_CODE (target_type) == VOID_TYPE)
+ permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
+ if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ permerror ("ISO C++ forbids using pointer to a function in subtraction");
+ if (TREE_CODE (target_type) == METHOD_TYPE)
+ permerror ("ISO C++ forbids using pointer to a method in subtraction");
/* First do the subtraction as integers;
then drop through to build the divide operator. */
@@ -4559,7 +4540,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
arg = build1 (CONVERT_EXPR, type, arg);
return arg;
}
- else if (pedantic && DECL_MAIN_P (arg))
+ else if (DECL_MAIN_P (arg))
{
/* ARM $3.4 */
if (complain & tf_error)
@@ -4655,7 +4636,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
/* Even if we're not being pedantic, we cannot allow this
extension when we're instantiating in a SFINAE
context. */
- if (! lvalue_p (arg) && (pedantic || complain == tf_none))
+ if (! lvalue_p (arg) && complain == tf_none)
{
if (complain & tf_error)
permerror ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
@@ -5443,7 +5424,8 @@ convert_member_func_to_ptr (tree type, tree expr)
|| TREE_CODE (intype) == METHOD_TYPE);
if (pedantic || warn_pmf2ptr)
- pedwarn ("converting from %qT to %qT", intype, type);
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpmf_conversions,
+ "converting from %qT to %qT", intype, type);
if (TREE_CODE (intype) == METHOD_TYPE)
expr = build_addr_func (expr);
@@ -6980,7 +6962,6 @@ check_return_expr (tree retval, bool *no_warning)
else
permerror ("return-statement with a value, in function "
"returning 'void'");
-
current_function_returns_null = 1;
/* There's really no value to return, after all. */
@@ -7347,7 +7328,8 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
if (pedantic)
{
tree bad_type = build_qualified_type (type, type_quals);
- pedwarn ("ignoring %qV qualifiers added to function type %qT",
+ pedwarn (OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
bad_type, type);
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index a30ff547f18..ee686fecf33 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -345,7 +345,7 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, int diag_type
if (diag_type == 1)
p_msg = warning0;
else if (diag_type == 2)
- p_msg = pedwarn;
+ p_msg = pedwarn0;
else
p_msg = error;