diff options
author | Richard Henderson <rth@redhat.com> | 2004-11-29 10:42:26 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-11-29 10:42:26 -0800 |
commit | b0c2dee9fbfb3ca4b768c17f14afcb89086c0eae (patch) | |
tree | eff32a57671c5494fd73715a4ef2663a8988ccd9 /gcc | |
parent | dda88f6f8500f5381afc5126b99290f52c810d20 (diff) | |
download | gcc-b0c2dee9fbfb3ca4b768c17f14afcb89086c0eae.zip gcc-b0c2dee9fbfb3ca4b768c17f14afcb89086c0eae.tar.gz gcc-b0c2dee9fbfb3ca4b768c17f14afcb89086c0eae.tar.bz2 |
re PR target/17224 (relocation truncated to fit: GPREL22)
PR target/17224
* config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets
outside the referenced object.
From-SVN: r91478
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/ia64/predicates.md | 40 |
2 files changed, 43 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c5801c2..ed8056a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-11-29 Richard Henderson <rth@redhat.com> + + PR target/17224 + * config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets + outside the referenced object. + 2004-11-29 Kazu Hirata <kazu@cs.umass.edu> * tree-if-conv.c (replace_phi_with_cond_modify_expr): Use diff --git a/gcc/config/ia64/predicates.md b/gcc/config/ia64/predicates.md index b66df84..6166612 100644 --- a/gcc/config/ia64/predicates.md +++ b/gcc/config/ia64/predicates.md @@ -74,21 +74,55 @@ (define_predicate "sdata_symbolic_operand" (match_code "symbol_ref,const") { + HOST_WIDE_INT offset = 0, size = 0; + switch (GET_CODE (op)) { case CONST: op = XEXP (op, 0); if (GET_CODE (op) != PLUS - || GET_CODE (XEXP (op, 0)) != SYMBOL_REF) + || GET_CODE (XEXP (op, 0)) != SYMBOL_REF + || GET_CODE (XEXP (op, 1)) != CONST_INT) return false; + offset = INTVAL (XEXP (op, 1)); op = XEXP (op, 0); /* FALLTHRU */ case SYMBOL_REF: if (CONSTANT_POOL_ADDRESS_P (op)) - return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold; + { + size = GET_MODE_SIZE (get_pool_mode (op)); + if (size > ia64_section_threshold) + return false; + } else - return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op); + { + tree t; + + if (!SYMBOL_REF_LOCAL_P (op) || !SYMBOL_REF_SMALL_P (op)) + return false; + + /* Note that in addition to DECLs, we can get various forms + of constants here. */ + t = SYMBOL_REF_DECL (op); + if (DECL_P (t)) + t = DECL_SIZE_UNIT (t); + else + t = TYPE_SIZE_UNIT (TREE_TYPE (t)); + if (t && host_integerp (t, 0)) + { + size = tree_low_cst (t, 0); + if (size < 0) + size = 0; + } + } + + /* Deny the stupid user trick of addressing outside the object. Such + things quickly result in GPREL22 relocation overflows. Of course, + they're also highly undefined. From a pure pedant's point of view + they deserve a slap on the wrist (such as provided by a relocation + overflow), but that just leads to bugzilla noise. */ + return (offset >= 0 && offset <= size); default: abort (); |