From f027e0a2a2067052c2e0a4782f24728125fa4da8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 14 Nov 2003 03:19:59 -0500 Subject: [PATCH] re PR middle-end/12526 ([tree-ssa] internal compiler error: Segmentation fault) PR middle-end/12526 * tree.c (build): A CALL_EXPR has side-effects if its arguments do. * calls.c (call_expr_flags): New fn. * tree.h: Declare it. From-SVN: r73589 --- gcc/ChangeLog | 7 +++++++ gcc/calls.c | 22 ++++++++++++++++++++++ gcc/tree.c | 14 +++++++++++--- gcc/tree.h | 1 + 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 818f5553719d..c8a3c96ce9d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-11-14 Jason Merrill + + PR middle-end/12526 + * tree.c (build): A CALL_EXPR has side-effects if its arguments do. + * calls.c (call_expr_flags): New fn. + * tree.h: Declare it. + 2003-11-13 Kazu Hirata * config/h8300/lib1funcs.asm (__udivsi3): Remove. diff --git a/gcc/calls.c b/gcc/calls.c index 18df59a92c27..abd4d6bb58b4 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -744,6 +744,28 @@ flags_from_decl_or_type (tree exp) return flags; } +/* Detect flags from a CALL_EXPR. */ + +int +call_expr_flags (tree t) +{ + int flags; + tree decl = get_callee_fndecl (t); + + if (decl) + flags = flags_from_decl_or_type (decl); + else + { + t = TREE_TYPE (TREE_OPERAND (t, 0)); + if (t && TREE_CODE (t) == POINTER_TYPE) + flags = flags_from_decl_or_type (TREE_TYPE (t)); + else + flags = 0; + } + + return flags; +} + /* Precompute all register parameters as described by ARGS, storing values into fields within the ARGS array. diff --git a/gcc/tree.c b/gcc/tree.c index 66e0afd73513..8466990ad5df 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2294,6 +2294,7 @@ build (enum tree_code code, tree tt, ...) int fro; int constant; va_list p; + tree node; va_start (p, tt); @@ -2380,10 +2381,17 @@ build (enum tree_code code, tree tt, ...) { /* Calls have side-effects, except those to const or pure functions. */ - tree fn = get_callee_fndecl (t); - - if (!fn || (!DECL_IS_PURE (fn) && !TREE_READONLY (fn))) + i = call_expr_flags (t); + if (!(i & (ECF_CONST | ECF_PURE))) TREE_SIDE_EFFECTS (t) = 1; + + /* And even those have side-effects if their arguments do. */ + else for (node = TREE_OPERAND (t, 1); node; node = TREE_CHAIN (node)) + if (TREE_SIDE_EFFECTS (TREE_VALUE (node))) + { + TREE_SIDE_EFFECTS (t) = 1; + break; + } } return t; diff --git a/gcc/tree.h b/gcc/tree.h index f94214ee57d8..2bad603cc548 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2941,6 +2941,7 @@ extern rtx emit_line_note (location_t); #define ECF_LIBCALL_BLOCK 4096 extern int flags_from_decl_or_type (tree); +extern int call_expr_flags (tree); extern int setjmp_call_p (tree); extern bool alloca_call_p (tree);