aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-06-30 00:50:45 +0000
committerJason Merrill <jason@redhat.com>2010-06-30 00:50:45 +0000
commit38fa736c8e7feae8874b3565f3bd35d37fd96461 (patch)
tree85c05d67287f91a060fe0e69e71f48258e217270
parentd14d66231fe5707c2b4b2d403e85c5bc393c6c55 (diff)
* class.c (type_has_virtual_destructor): New.
* cp-tree.h: Declare it. * semantics.c (trait_expr_value): Use it. * call.c (build_over_call): Only give warnings with tf_warning. * name-lookup.c (pop_scope): Handle NULL_TREE. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@161578 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/class.c19
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c1
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/cp/tree.c23
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted19.C21
-rw-r--r--gcc/testsuite/g++.dg/expr/string-1.C4
-rw-r--r--gcc/testsuite/g++.dg/template/error23.C4
12 files changed, 85 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7eaca7fc688..bc02bd02c43 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2010-06-29 Jason Merrill <jason@redhat.com>
+ * class.c (type_has_virtual_destructor): New.
+ * cp-tree.h: Declare it.
+ * semantics.c (trait_expr_value): Use it.
+
+ * call.c (build_over_call): Only give warnings with tf_warning.
+
+ * name-lookup.c (pop_scope): Handle NULL_TREE.
+
* cp-tree.h (TYPE_HAS_ASSIGN_REF): Rename to TYPE_HAS_COPY_ASSIGN.
(TYPE_HAS_CONST_ASSIGN_REF): Rename to TYPE_HAS_CONST_COPY_ASSIGN.
(TYPE_HAS_INIT_REF): Rename to TYPE_HAS_COPY_CTOR.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c05e5a1ec2f..852c7ea983e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5600,7 +5600,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
}
/* Give any warnings we noticed during overload resolution. */
- if (cand->warnings)
+ if (cand->warnings && (complain & tf_warning))
{
struct candidate_warning *w;
for (w = cand->warnings; w; w = w->next)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 3a87555876c..bfd311382e1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3838,7 +3838,9 @@ check_methods (tree t)
if (DECL_PURE_VIRTUAL_P (x))
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
}
- /* All user-provided destructors are non-trivial. */
+ /* All user-provided destructors are non-trivial.
+ Constructors and assignment ops are handled in
+ grok_special_member_properties. */
if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
}
@@ -4260,6 +4262,21 @@ type_has_user_provided_default_constructor (tree t)
return false;
}
+/* Returns true iff class TYPE has a virtual destructor. */
+
+bool
+type_has_virtual_destructor (tree type)
+{
+ tree dtor;
+
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ gcc_assert (COMPLETE_TYPE_P (type));
+ dtor = CLASSTYPE_DESTRUCTORS (type);
+ return (dtor && DECL_VIRTUAL_P (dtor));
+}
+
/* Remove all zero-width bit-fields from T. */
static void
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1b3c2f0a0f9..bfdf036f2aa 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4655,6 +4655,7 @@ extern tree in_class_defaulted_default_constructor (tree);
extern bool user_provided_p (tree);
extern bool type_has_user_provided_constructor (tree);
extern bool type_has_user_provided_default_constructor (tree);
+extern bool type_has_virtual_destructor (tree);
extern void defaulted_late_check (tree);
extern bool defaultable_fn_check (tree);
extern void fixup_type_variants (tree);
@@ -5280,6 +5281,7 @@ extern bool pod_type_p (const_tree);
extern bool layout_pod_type_p (const_tree);
extern bool std_layout_type_p (const_tree);
extern bool trivial_type_p (const_tree);
+extern bool trivially_copyable_p (const_tree);
extern bool type_has_nontrivial_default_init (const_tree);
extern bool type_has_nontrivial_copy_init (const_tree);
extern bool class_tmpl_impl_spec_p (const_tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 10112437fe9..0c2f7e57266 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10295,6 +10295,7 @@ grok_special_member_properties (tree decl)
TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1;
}
}
+ /* Destructors are handled in check_methods. */
}
/* Check a constructor DECL has the correct form. Complains
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4e40e3b555a..67131190305 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2480,6 +2480,8 @@ push_scope (tree t)
void
pop_scope (tree t)
{
+ if (t == NULL_TREE)
+ return;
if (TREE_CODE (t) == NAMESPACE_DECL)
pop_decl_namespace ();
else if CLASS_TYPE_P (t)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9dae90b4c8f..adc5e7fe6ba 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5104,8 +5104,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
case CPTK_HAS_VIRTUAL_DESTRUCTOR:
- return (CLASS_TYPE_P (type1)
- && (t = locate_dtor (type1, NULL)) && DECL_VIRTUAL_P (t));
+ return type_has_virtual_destructor (type1);
case CPTK_IS_ABSTRACT:
return (CLASS_TYPE_P (type1) && CLASSTYPE_PURE_VIRTUALS (type1));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f7ce655eb19..72369244b43 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2381,22 +2381,37 @@ type_has_nontrivial_copy_init (const_tree t)
return 0;
}
-/* Returns 1 iff type T is a trivial type, as defined in [basic.types]. */
+/* Returns 1 iff type T is a trivially copyable type, as defined in
+ [basic.types] and [class]. */
bool
-trivial_type_p (const_tree t)
+trivially_copyable_p (const_tree t)
{
t = strip_array_types (CONST_CAST_TREE (t));
if (CLASS_TYPE_P (t))
- return (TYPE_HAS_TRIVIAL_DFLT (t)
- && TYPE_HAS_TRIVIAL_COPY_CTOR (t)
+ return (TYPE_HAS_TRIVIAL_COPY_CTOR (t)
&& TYPE_HAS_TRIVIAL_COPY_ASSIGN (t)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (t));
else
return scalarish_type_p (t);
}
+/* Returns 1 iff type T is a trivial type, as defined in [basic.types] and
+ [class]. */
+
+bool
+trivial_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return (TYPE_HAS_TRIVIAL_DFLT (t)
+ && trivially_copyable_p (t));
+ else
+ return scalarish_type_p (t);
+}
+
/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
bool
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4e37174f77c..2d1aa2d74ed 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-06-29 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/defaulted19.C: New.
+
+ * g++.dg/expr/string-1.C: Fix for -std=c++0x.
+ * g++.dg/template/error23.C: Fix for -std=c++0x.
+
2010-06-29 Janus Weil <janus@gcc.gnu.org>
PR fortran/44718
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted19.C b/gcc/testsuite/g++.dg/cpp0x/defaulted19.C
new file mode 100644
index 00000000000..ea33df39838
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted19.C
@@ -0,0 +1,21 @@
+// We allocate a cookie to help us run the destructor even if it's deleted.
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+struct A
+{
+ ~A() = delete;
+};
+
+void *p = 0;
+void *operator new[](__SIZE_TYPE__ t)
+{
+ p = ::operator new (t);
+ return p;
+}
+
+int main()
+{
+ A* ap = new A[5];
+ return ap == p;
+}
diff --git a/gcc/testsuite/g++.dg/expr/string-1.C b/gcc/testsuite/g++.dg/expr/string-1.C
index 3901427f439..9a0a5ff7b45 100644
--- a/gcc/testsuite/g++.dg/expr/string-1.C
+++ b/gcc/testsuite/g++.dg/expr/string-1.C
@@ -1,9 +1,11 @@
// { dg-do compile }
// This testcase used to seg fault (PR c++/38648)
+// { dg-prune-output "initializer lists" }
+
char a[1];
-int foo( // { dg-error "extended initializer lists only available" }
+int foo(
{
a = ""; // { dg-error "" }
return 0; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/error23.C b/gcc/testsuite/g++.dg/template/error23.C
index 8e5dee76dda..f21d8d9d07c 100644
--- a/gcc/testsuite/g++.dg/template/error23.C
+++ b/gcc/testsuite/g++.dg/template/error23.C
@@ -8,10 +8,10 @@ struct nullptr_type {
operator T* ( void ) const {
return ( 0 );
}
-} const nullptr;
+} const nullptr_ob;
int main ( void ) {
- 0 == nullptr; // { dg-error "match" }
+ 0 == nullptr_ob; // { dg-error "match" }
}