PR c/22098
* langhooks.h (struct lang_hooks): Add expr_to_decl.
* langhooks.c (lhd_expr_to_decl): New.
* langhooks-def.h (lhd_expr_to_decl, LANG_HOOKS_EXPR_TO_DECL):
New.
(LANG_HOOKS_INITIALIZER): Update.
* tree.c (recompute_tree_invarant_for_addr_expr): Call
expr_to_decl langhook.
* c-tree.h (c_expr_to_decl): Declare.
* c-typeck.c (c_expr_to_decl): New.
(build_unary_op): Do not handle ADDR_EXPR of COMPOUND_LITERAL_EXPR
specially.
* c-objc-common.h (LANG_HOOKS_EXPR_TO_DECL): Define.
testsuite:
* gcc.c-torture/compile/pr22013-1.c,
gcc.c-torture/execute/pr22098-1.c,
gcc.c-torture/execute/pr22098-2.c,
gcc.c-torture/execute/pr22098-3.c: New tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101630
138bc75d-0d04-0410-961f-
82ee72b054a4
2005-07-05 Joseph S. Myers <joseph@codesourcery.com>
+ PR c/22013
+ PR c/22098
+ * langhooks.h (struct lang_hooks): Add expr_to_decl.
+ * langhooks.c (lhd_expr_to_decl): New.
+ * langhooks-def.h (lhd_expr_to_decl, LANG_HOOKS_EXPR_TO_DECL):
+ New.
+ (LANG_HOOKS_INITIALIZER): Update.
+ * tree.c (recompute_tree_invarant_for_addr_expr): Call
+ expr_to_decl langhook.
+ * c-tree.h (c_expr_to_decl): Declare.
+ * c-typeck.c (c_expr_to_decl): New.
+ (build_unary_op): Do not handle ADDR_EXPR of COMPOUND_LITERAL_EXPR
+ specially.
+ * c-objc-common.h (LANG_HOOKS_EXPR_TO_DECL): Define.
+
+2005-07-05 Joseph S. Myers <joseph@codesourcery.com>
+
PR c/22308
* c-decl.c (finish_struct): Also copy C_TYPE_FIELDS_READONLY,
C_TYPE_FIELDS_VOLATILE and C_TYPE_VARIABLE_SIZE to type variants.
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
#undef LANG_HOOKS_TO_TARGET_CHARSET
#define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
+#undef LANG_HOOKS_EXPR_TO_DECL
+#define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
/* The C front end's scoping structure is very different from
that expected by the language-independent code; it is best
extern tree c_finish_goto_ptr (tree);
extern void c_begin_vm_scope (unsigned int);
extern void c_end_vm_scope (unsigned int);
+extern tree c_expr_to_decl (tree, bool *, bool *, bool *);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
val = build1 (ADDR_EXPR, argtype, arg);
- if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
- TREE_INVARIANT (val) = TREE_CONSTANT (val) = 1;
-
return val;
default:
leaving those to give errors later? */
return c_common_truthvalue_conversion (expr);
}
+\f
+
+/* Convert EXPR to a contained DECL, updating *TC, *TI and *SE as
+ required. */
+
+tree
+c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
+ bool *ti ATTRIBUTE_UNUSED, bool *se)
+{
+ if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
+ {
+ tree decl = COMPOUND_LITERAL_EXPR_DECL (expr);
+ /* Executing a compound literal inside a function reinitializes
+ it. */
+ if (!TREE_STATIC (decl))
+ *se = true;
+ return decl;
+ }
+ else
+ return expr;
+}
extern tree lhd_expr_size (tree);
extern size_t lhd_tree_size (enum tree_code);
extern HOST_WIDE_INT lhd_to_target_charset (HOST_WIDE_INT);
+extern tree lhd_expr_to_decl (tree, bool *, bool *, bool *);
/* Declarations of default tree inlining hooks. */
extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
#define LANG_HOOKS_TREE_SIZE lhd_tree_size
#define LANG_HOOKS_TYPES_COMPATIBLE_P lhd_types_compatible_p
#define LANG_HOOKS_BUILTIN_FUNCTION builtin_function
+#define LANG_HOOKS_EXPR_TO_DECL lhd_expr_to_decl
#define LANG_HOOKS_TO_TARGET_CHARSET lhd_to_target_charset
#define LANG_HOOKS_FUNCTION_INIT lhd_do_nothing_f
LANG_HOOKS_GIMPLIFY_EXPR, \
LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
LANG_HOOKS_BUILTIN_FUNCTION, \
+ LANG_HOOKS_EXPR_TO_DECL, \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
{
return c;
}
+
+tree
+lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
+ bool *ti ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSED)
+{
+ return expr;
+}
enum built_in_class bt_class,
const char *library_name, tree attrs);
+ /* Called by recompute_tree_invarant_for_addr_expr to go from EXPR
+ to a contained expression or DECL, possibly updating *TC, *TI or
+ *SE if in the process TREE_CONSTANT, TREE_INVARIANT or
+ TREE_SIDE_EFFECTS need updating. */
+ tree (*expr_to_decl) (tree expr, bool *tc, bool *ti, bool *se);
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
2005-07-05 Joseph S. Myers <joseph@codesourcery.com>
+ PR c/22013
+ PR c/22098
+ * gcc.c-torture/compile/pr22013-1.c,
+ gcc.c-torture/execute/pr22098-1.c,
+ gcc.c-torture/execute/pr22098-2.c,
+ gcc.c-torture/execute/pr22098-3.c: New tests.
+
+2005-07-05 Joseph S. Myers <joseph@codesourcery.com>
+
PR c/22308
* gcc.dg/pr22308-1.c: New test.
--- /dev/null
+typedef unsigned short W;
+typedef const W *P;
+
+extern void g(P);
+
+void
+f ()
+{
+ const P s = (const W []){ 'R' };
+ g (s);
+}
--- /dev/null
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int
+main (void)
+{
+ int a = 0;
+ int *p;
+ size_t b;
+ b = (size_t)(p = &(int []){0, 1, 2}[++a]);
+ if (a != 1 || *p != 1 || *(int *)b != 1)
+ abort ();
+ exit (0);
+}
--- /dev/null
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int
+main (void)
+{
+ int a = 0;
+ int *p;
+ size_t b;
+ b = (size_t)(p = &(int []){0, 1, 2}[1]);
+ if (*p != 1 || *(int *)b != 1)
+ abort ();
+ exit (0);
+}
--- /dev/null
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int n = 0;
+int f (void) { return ++n; }
+int
+main (void)
+{
+ int a = 0;
+ int *p;
+ size_t b;
+ b = (size_t)(p = &(int []){0, f(), 2}[1]);
+ if (*p != 1 || *(int *)b != 1 || n != 1)
+ abort ();
+ exit (0);
+}
UPDATE_TITCSE (TREE_OPERAND (node, 2));
}
+ node = lang_hooks.expr_to_decl (node, &tc, &ti, &se);
+
/* Now see what's inside. If it's an INDIRECT_REF, copy our properties from
the address, since &(*a)->b is a form of addition. If it's a decl, it's
invariant and constant if the decl is static. It's also invariant if it's