From: Jason Merrill Date: Thu, 5 Mar 2009 14:10:07 +0000 (-0500) Subject: re PR c++/38908 (Unexplained "'' is used uninitialized in this function... X-Git-Tag: releases/gcc-4.4.0~347 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2588c9e970ebea8cd91d3ba9b38ccd909e063c30;p=thirdparty%2Fgcc.git re PR c++/38908 (Unexplained "'' is used uninitialized in this function" warning in cc1plus -m64) PR c++/38908 * class.c (is_really_empty_class): New fn. * cp-tree.h: Declare it. * cp-objcp-common.c (cp_expr_size): Use it. From-SVN: r144643 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 187ade406781..31a626bc1ade 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2009-03-04 Jason Merrill + PR c++/38908 + * class.c (is_really_empty_class): New fn. + * cp-tree.h: Declare it. + * cp-objcp-common.c (cp_expr_size): Use it. + PR c++/13549 * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR. * parser.c (cp_parser_postfix_expression): Call it for diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ae89218a700d..b8553effc03a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6461,7 +6461,7 @@ is_empty_class (tree type) if (type == error_mark_node) return 0; - if (! MAYBE_CLASS_TYPE_P (type)) + if (! CLASS_TYPE_P (type)) return 0; /* In G++ 3.2, whether or not a class was empty was determined by @@ -6501,6 +6501,37 @@ contains_empty_class_p (tree type) return false; } +/* Returns true if TYPE contains no actual data, just various + possible combinations of empty classes. */ + +bool +is_really_empty_class (tree type) +{ + if (is_empty_class (type)) + return true; + if (CLASS_TYPE_P (type)) + { + tree field; + tree binfo; + tree base_binfo; + int i; + + for (binfo = TYPE_BINFO (type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (!is_really_empty_class (BINFO_TYPE (base_binfo))) + return false; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !is_really_empty_class (TREE_TYPE (field))) + return false; + return true; + } + else if (TREE_CODE (type) == ARRAY_TYPE) + return is_really_empty_class (TREE_TYPE (type)); + return false; +} + /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 7d2e870bc80c..fefafb1ac7ea 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -101,7 +101,7 @@ cp_expr_size (const_tree exp) constructed, this is a valid transformation. */ || CP_AGGREGATE_TYPE_P (type)) /* This would be wrong for a type with virtual bases. */ - return (is_empty_class (type) + return (is_really_empty_class (type) ? size_zero_node : CLASSTYPE_SIZE_UNIT (type)); else diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b6bf7d40da09..aedf5b96749b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4240,6 +4240,7 @@ extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); extern void init_class_processing (void); extern int is_empty_class (tree); +extern bool is_really_empty_class (tree); extern void pushclass (tree); extern void popclass (void); extern void push_nested_class (tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f71de1c30e9b..37c4074dc873 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-05 Jason Merrill + + PR c++/38908 + * g++.dg/warn/Wuninitialized-3.C: New test. + 2009-03-05 Jakub Jelinek PR debug/39379 diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C new file mode 100644 index 000000000000..dc3be3f67fab --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C @@ -0,0 +1,17 @@ +// PR C++/38908 +// { dg-options "-Wuninitialized -O" } + +struct empty {}; + +struct dfs_visitor { + dfs_visitor() { } + empty m_vis; +}; + +void bar(const dfs_visitor&); +void foo(void) +{ + dfs_visitor vis; + dfs_visitor vis2 = vis; + bar (vis2); +}