From: Richard Kenner Date: Thu, 17 Nov 2005 21:03:50 +0000 (+0000) Subject: re PR ada/22333 (ACATS FAIL c34007p c34007r c45282b spurious discriminant CONSTRAINT_... X-Git-Tag: releases/gcc-4.1.0~734 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=115a82d3f11547152be8579f1302b2fd544e736f;p=thirdparty%2Fgcc.git re PR ada/22333 (ACATS FAIL c34007p c34007r c45282b spurious discriminant CONSTRAINT_ERROR) PR ada/22333 * trans.c (gnat_gimplify_expr, case ADDR_EXPR): Always make a temporary if taking the address of something that is neither reference, declaration, or constant, since the gimplifier can't handle that case. From-SVN: r107134 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 75651bc7bc49..78aaba7a9a62 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2005-11-17 Richard Kenner + + PR ada/22333 + * trans.c (gnat_gimplify_expr, case ADDR_EXPR): Always make + a temporary if taking the address of something that is neither + reference, declaration, or constant, since the gimplifier + can't handle that case. + 2005-11-17 Laurent GUERBY PR ada/24857 diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index 918f374b5daa..c71267200030 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -4570,6 +4570,7 @@ int gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) { tree expr = *expr_p; + tree op; if (IS_ADA_STMT (expr)) return gnat_gimplify_stmt (expr_p); @@ -4600,25 +4601,50 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) return GS_OK; case ADDR_EXPR: + op = TREE_OPERAND (expr, 0); + /* If we're taking the address of a constant CONSTRUCTOR, force it to be put into static memory. We know it's going to be readonly given the semantics we have and it's required to be static memory in - the case when the reference is in an elaboration procedure. */ - if (TREE_CODE (TREE_OPERAND (expr, 0)) == CONSTRUCTOR - && TREE_CONSTANT (TREE_OPERAND (expr, 0))) + the case when the reference is in an elaboration procedure. */ + if (TREE_CODE (op) == CONSTRUCTOR && TREE_CONSTANT (op)) { - tree new_var - = create_tmp_var (TREE_TYPE (TREE_OPERAND (expr, 0)), "C"); + tree new_var = create_tmp_var (TREE_TYPE (op), "C"); TREE_READONLY (new_var) = 1; TREE_STATIC (new_var) = 1; TREE_ADDRESSABLE (new_var) = 1; - DECL_INITIAL (new_var) = TREE_OPERAND (expr, 0); + DECL_INITIAL (new_var) = op; + + TREE_OPERAND (expr, 0) = new_var; + recompute_tree_invarant_for_addr_expr (expr); + return GS_ALL_DONE; + } + + /* Otherwise, if we are taking the address of something that is neither + reference, declaration, or constant, make a variable for the operand + here and then take its address. If we don't do it this way, we may + confuse the gimplifier because it needs to know the variable is + addressable at this point. This duplicates code in + internal_get_tmp_var, which is unfortunate. */ + else if (TREE_CODE_CLASS (TREE_CODE (op)) != tcc_reference + && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_declaration + && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_constant) + { + tree new_var = create_tmp_var (TREE_TYPE (op), "A"); + tree mod = build (MODIFY_EXPR, TREE_TYPE (op), new_var, op); + + TREE_ADDRESSABLE (new_var) = 1; + + if (EXPR_HAS_LOCATION (op)) + SET_EXPR_LOCUS (mod, EXPR_LOCUS (op)); + gimplify_and_add (mod, pre_p); TREE_OPERAND (expr, 0) = new_var; recompute_tree_invarant_for_addr_expr (expr); return GS_ALL_DONE; } + return GS_UNHANDLED; case COMPONENT_REF: