backport: re PR debug/54828 (ICE in based_loc_descr at dwarf2out.c:10560 with -g -O0)

Backported from mainline
	2012-10-24  Jakub Jelinek  <jakub@redhat.com>

	PR debug/54828
	* gimple.h (is_gimple_sizepos): New inline function.
	* gimplify.c (gimplify_one_sizepos): Use it.  Remove useless
	final assignment to expr variable.
	* tree.c (RETURN_TRUE_IF_VAR): Return true also if
	!TYPE_SIZES_GIMPLIFIED (type) and _t is going to be gimplified
	into a local temporary.

	* g++.dg/debug/pr54828.C: New test.

From-SVN: r193166
This commit is contained in:
Jakub Jelinek 2012-11-05 16:09:28 +01:00 committed by Jakub Jelinek
parent 740ee7c578
commit 5c61050792
6 changed files with 55 additions and 5 deletions

View File

@ -1,6 +1,16 @@
2012-11-05 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-10-24 Jakub Jelinek <jakub@redhat.com>
PR debug/54828
* gimple.h (is_gimple_sizepos): New inline function.
* gimplify.c (gimplify_one_sizepos): Use it. Remove useless
final assignment to expr variable.
* tree.c (RETURN_TRUE_IF_VAR): Return true also if
!TYPE_SIZES_GIMPLIFIED (type) and _t is going to be gimplified
into a local temporary.
2012-10-10 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/54877

View File

@ -1087,6 +1087,24 @@ struct gimplify_ctx
bool in_cleanup_point_expr;
};
/* Return true if gimplify_one_sizepos doesn't need to gimplify
expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
fields). */
static inline bool
is_gimple_sizepos (tree expr)
{
/* gimplify_one_sizepos doesn't need to do anything if the value isn't there,
is constant, or contains A PLACEHOLDER_EXPR. We also don't want to do
anything if it's already a VAR_DECL. If it's a VAR_DECL from another
function, the gimplifier will want to replace it with a new variable,
but that will cause problems if this type is from outside the function.
It's OK to have that here. */
return (expr == NULL_TREE
|| TREE_CONSTANT (expr)
|| TREE_CODE (expr) == VAR_DECL
|| CONTAINS_PLACEHOLDER_P (expr));
}
extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
bool (*) (tree), fallback_t);
extern void gimplify_type_sizes (tree, gimple_seq *);

View File

@ -7948,9 +7948,7 @@ gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
will want to replace it with a new variable, but that will cause problems
if this type is from outside the function. It's OK to have that here. */
if (expr == NULL_TREE || TREE_CONSTANT (expr)
|| TREE_CODE (expr) == VAR_DECL
|| CONTAINS_PLACEHOLDER_P (expr))
if (is_gimple_sizepos (expr))
return;
type = TREE_TYPE (expr);

View File

@ -1,6 +1,11 @@
2012-11-05 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-10-24 Jakub Jelinek <jakub@redhat.com>
PR debug/54828
* g++.dg/debug/pr54828.C: New test.
2012-10-23 Jakub Jelinek <jakub@redhat.com>
PR c++/54988

View File

@ -0,0 +1,14 @@
// PR debug/54828
// { dg-do compile }
// { dg-options "-g" }
struct T { T (); virtual ~T (); };
struct S : public virtual T { S (); virtual ~S (); };
int v;
void foo (char *);
S::S ()
{
char s[v];
foo (s);
}

View File

@ -8445,14 +8445,19 @@ variably_modified_type_p (tree type, tree fn)
tree t;
/* Test if T is either variable (if FN is zero) or an expression containing
a variable in FN. */
a variable in FN. If TYPE isn't gimplified, return true also if
gimplify_one_sizepos would gimplify the expression into a local
variable. */
#define RETURN_TRUE_IF_VAR(T) \
do { tree _t = (T); \
if (_t != NULL_TREE \
&& _t != error_mark_node \
&& TREE_CODE (_t) != INTEGER_CST \
&& TREE_CODE (_t) != PLACEHOLDER_EXPR \
&& (!fn || walk_tree (&_t, find_var_from_fn, fn, NULL))) \
&& (!fn \
|| (!TYPE_SIZES_GIMPLIFIED (type) \
&& !is_gimple_sizepos (_t)) \
|| walk_tree (&_t, find_var_from_fn, fn, NULL))) \
return true; } while (0)
if (type == error_mark_node)