Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4
cross-ia64-gcc-icecream-backend
pr43270.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr43270.diff of Package cross-ia64-gcc-icecream-backend
Index: gcc/tree-vrp.c =================================================================== *** gcc/tree-vrp.c.orig 2010-03-08 15:10:59.000000000 +0100 --- gcc/tree-vrp.c 2010-03-08 16:11:47.000000000 +0100 *************** check_array_ref (location_t location, tr *** 4981,5003 **** { value_range_t* vr = NULL; tree low_sub, up_sub; ! tree low_bound, up_bound = array_ref_up_bound (ref); low_sub = up_sub = TREE_OPERAND (ref, 1); ! if (!up_bound || TREE_NO_WARNING (ref) ! || TREE_CODE (up_bound) != INTEGER_CST ! /* Can not check flexible arrays. */ ! || (TYPE_SIZE (TREE_TYPE (ref)) == NULL_TREE ! && TYPE_DOMAIN (TREE_TYPE (ref)) != NULL_TREE ! && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (ref))) == NULL_TREE) ! /* Accesses after the end of arrays of size 0 (gcc ! extension) and 1 are likely intentional ("struct ! hack"). */ ! || compare_tree_int (up_bound, 1) <= 0) return; low_bound = array_ref_low_bound (ref); if (TREE_CODE (low_sub) == SSA_NAME) { --- 4981,5026 ---- { value_range_t* vr = NULL; tree low_sub, up_sub; ! tree low_bound, up_bound, up_bound_p1; ! tree base; ! ! if (TREE_NO_WARNING (ref)) ! return; low_sub = up_sub = TREE_OPERAND (ref, 1); + up_bound = array_ref_up_bound (ref); ! /* Can not check flexible arrays. */ ! if (!up_bound ! || TREE_CODE (up_bound) != INTEGER_CST) return; + /* Accesses to trailing arrays via pointers may access storage + beyond the types array bounds. */ + base = get_base_address (ref); + if (base + && INDIRECT_REF_P (base)) + { + tree cref, next = NULL_TREE; + + if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF) + return; + + cref = TREE_OPERAND (ref, 0); + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE) + for (next = TREE_CHAIN (TREE_OPERAND (cref, 1)); + next && TREE_CODE (next) != FIELD_DECL; + next = TREE_CHAIN (next)) + ; + + /* If this is the last field in a struct type or a field in a + union type do not warn. */ + if (!next) + return; + } + low_bound = array_ref_low_bound (ref); + up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, integer_one_node, 0); if (TREE_CODE (low_sub) == SSA_NAME) { *************** check_array_ref (location_t location, tr *** 5022,5035 **** } } else if (TREE_CODE (up_sub) == INTEGER_CST ! && tree_int_cst_lt (up_bound, up_sub) ! && !tree_int_cst_equal (up_bound, up_sub) ! && (!ignore_off_by_one ! || !tree_int_cst_equal (int_const_binop (PLUS_EXPR, ! up_bound, ! integer_one_node, ! 0), ! up_sub))) { warning_at (location, OPT_Warray_bounds, "array subscript is above array bounds"); --- 5045,5055 ---- } } else if (TREE_CODE (up_sub) == INTEGER_CST ! && (ignore_off_by_one ! ? (tree_int_cst_lt (up_bound, up_sub) ! && !tree_int_cst_equal (up_bound_p1, up_sub)) ! : (tree_int_cst_lt (up_bound, up_sub) ! || tree_int_cst_equal (up_bound_p1, up_sub)))) { warning_at (location, OPT_Warray_bounds, "array subscript is above array bounds"); Index: gcc/testsuite/g++.dg/warn/Warray-bounds-4.C =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- gcc/testsuite/g++.dg/warn/Warray-bounds-4.C 2010-03-08 16:12:00.000000000 +0100 *************** *** 0 **** --- 1,37 ---- + // { dg-do compile } + // { dg-options "-O2 -Warray-bounds" } + + class String + { + public: + virtual unsigned long length() const = 0; + virtual char get(unsigned long index) const = 0; + virtual void set(unsigned long index, char value) = 0; + virtual char& operator[] (unsigned long value) = 0; + virtual ~String() {}; + }; + + template<unsigned long size> class FixedString : public String + { + private: + char contents[size]; + + public: + virtual unsigned long length() const { return size; } + virtual char get(unsigned long index) const { return contents[index]; } + virtual void set(unsigned long index, char value) { contents[index] = value; } + virtual char& operator[] (unsigned long index) { return contents[index]; } + + FixedString() { contents[0] = '\0'; } // { dg-warning "above array bounds" } + }; + + void print_length (const String& string); + + int main() + { + const FixedString<0> empty; + + print_length(empty); + + return 0; + } Index: gcc/tree-ssa-sccvn.h =================================================================== *** gcc/tree-ssa-sccvn.h.orig 2010-03-08 15:10:59.000000000 +0100 --- gcc/tree-ssa-sccvn.h 2010-03-08 15:11:08.000000000 +0100 *************** unsigned int get_next_value_id (void); *** 204,207 **** --- 204,208 ---- unsigned int get_constant_value_id (tree); unsigned int get_or_alloc_constant_value_id (tree); bool value_id_constant_p (unsigned int); + tree fully_constant_vn_reference_p (vn_reference_t); #endif /* TREE_SSA_SCCVN_H */ Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c.orig 2010-03-08 15:10:59.000000000 +0100 --- gcc/tree-ssa-pre.c 2010-03-08 15:11:08.000000000 +0100 *************** do_unary: *** 1231,1279 **** case REFERENCE: { vn_reference_t ref = PRE_EXPR_REFERENCE (e); ! VEC (vn_reference_op_s, heap) *operands = ref->operands; ! vn_reference_op_t op; ! ! /* Try to simplify the translated expression if it is ! a call to a builtin function with at most two arguments. */ ! op = VEC_index (vn_reference_op_s, operands, 0); ! if (op->opcode == CALL_EXPR ! && TREE_CODE (op->op0) == ADDR_EXPR ! && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL ! && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0)) ! && VEC_length (vn_reference_op_s, operands) >= 2 ! && VEC_length (vn_reference_op_s, operands) <= 3) ! { ! vn_reference_op_t arg0, arg1 = NULL; ! bool anyconst = false; ! arg0 = VEC_index (vn_reference_op_s, operands, 1); ! if (VEC_length (vn_reference_op_s, operands) > 2) ! arg1 = VEC_index (vn_reference_op_s, operands, 2); ! if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant ! || (arg0->opcode == ADDR_EXPR ! && is_gimple_min_invariant (arg0->op0))) ! anyconst = true; ! if (arg1 ! && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant ! || (arg1->opcode == ADDR_EXPR ! && is_gimple_min_invariant (arg1->op0)))) ! anyconst = true; ! if (anyconst) ! { ! tree folded = build_call_expr (TREE_OPERAND (op->op0, 0), ! arg1 ? 2 : 1, ! arg0->op0, ! arg1 ? arg1->op0 : NULL); ! if (folded ! && TREE_CODE (folded) == NOP_EXPR) ! folded = TREE_OPERAND (folded, 0); ! if (folded ! && is_gimple_min_invariant (folded)) ! return get_or_alloc_expr_for_constant (folded); ! } ! } ! return e; ! } default: return e; } --- 1231,1241 ---- case REFERENCE: { vn_reference_t ref = PRE_EXPR_REFERENCE (e); ! tree folded; ! if ((folded = fully_constant_vn_reference_p (ref))) ! return get_or_alloc_expr_for_constant (folded); ! return e; ! } default: return e; } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c.orig 2010-03-08 15:10:59.000000000 +0100 --- gcc/tree-ssa-sccvn.c 2010-03-08 16:08:09.000000000 +0100 *************** vn_reference_lookup_pieces (tree vuse, a *** 1234,1239 **** --- 1234,1305 ---- return NULL_TREE; } + tree + fully_constant_vn_reference_p (vn_reference_t ref) + { + VEC (vn_reference_op_s, heap) *operands = ref->operands; + vn_reference_op_t op; + + /* Try to simplify the translated expression if it is + a call to a builtin function with at most two arguments. */ + op = VEC_index (vn_reference_op_s, operands, 0); + if (op->opcode == CALL_EXPR + && TREE_CODE (op->op0) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL + && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0)) + && VEC_length (vn_reference_op_s, operands) >= 2 + && VEC_length (vn_reference_op_s, operands) <= 3) + { + vn_reference_op_t arg0, arg1 = NULL; + bool anyconst = false; + arg0 = VEC_index (vn_reference_op_s, operands, 1); + if (VEC_length (vn_reference_op_s, operands) > 2) + arg1 = VEC_index (vn_reference_op_s, operands, 2); + if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant + || (arg0->opcode == ADDR_EXPR + && is_gimple_min_invariant (arg0->op0))) + anyconst = true; + if (arg1 + && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant + || (arg1->opcode == ADDR_EXPR + && is_gimple_min_invariant (arg1->op0)))) + anyconst = true; + if (anyconst) + { + tree folded = build_call_expr (TREE_OPERAND (op->op0, 0), + arg1 ? 2 : 1, + arg0->op0, + arg1 ? arg1->op0 : NULL); + if (folded + && TREE_CODE (folded) == NOP_EXPR) + folded = TREE_OPERAND (folded, 0); + if (folded + && is_gimple_min_invariant (folded)) + return folded; + } + } + + /* Simplify reads from constant strings. */ + else if (op->opcode == ARRAY_REF + && TREE_CODE (op->op0) == INTEGER_CST + && integer_zerop (op->op1) + && VEC_length (vn_reference_op_s, operands) == 2) + { + vn_reference_op_t arg0; + arg0 = VEC_index (vn_reference_op_s, operands, 1); + if (arg0->opcode == STRING_CST + && TYPE_MODE (op->type) == TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0->op0))) + && GET_MODE_CLASS (TYPE_MODE (op->type)) == MODE_INT + && GET_MODE_SIZE (TYPE_MODE (op->type)) == 1 + && compare_tree_int (op->op0, TREE_STRING_LENGTH (arg0->op0)) < 0) + return build_int_cst_type (op->type, + (TREE_STRING_POINTER (arg0->op0) + [TREE_INT_CST_LOW (op->op0)])); + } + + return NULL_TREE; + } + /* Lookup OP in the current hash table, and return the resulting value number if it exists in the hash table. Return NULL_TREE if it does not exist in the hash table or if the result field of the structure *************** vn_reference_lookup (tree op, tree vuse, *** 1246,1251 **** --- 1312,1318 ---- { VEC (vn_reference_op_s, heap) *operands; struct vn_reference_s vr1; + tree cst; if (vnresult) *vnresult = NULL; *************** vn_reference_lookup (tree op, tree vuse, *** 1255,1260 **** --- 1322,1329 ---- vr1.type = TREE_TYPE (op); vr1.set = get_alias_set (op); vr1.hashcode = vn_reference_compute_hash (&vr1); + if ((cst = fully_constant_vn_reference_p (&vr1))) + return cst; if (maywalk && vr1.vuse) Index: gcc/testsuite/gcc.dg/Warray-bounds-7.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- gcc/testsuite/gcc.dg/Warray-bounds-7.c 2010-03-08 15:11:08.000000000 +0100 *************** *** 0 **** --- 1,13 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -Warray-bounds" } */ + + char *p; + + int main() + { + p = ""; + if (p[0] == 0 + || (p[0] == '_' && p[1] == 0)) /* { dg-bogus "array bounds" "" } */ + return 0; + return 1; + } Index: gcc/Makefile.in =================================================================== *** gcc/Makefile.in.orig 2010-03-08 15:10:59.000000000 +0100 --- gcc/Makefile.in 2010-03-08 15:11:08.000000000 +0100 *************** GCC_WARN_CXXFLAGS = $(LOOSE_WARN) $($(@D *** 183,188 **** --- 183,189 ---- build/gengtype-lex.o-warn = -Wno-error # mips-tfile.c contains -Wcast-qual warnings. mips-tfile.o-warn = -Wno-error + expmed.o-warn = -Wno-error # All warnings have to be shut off in stage1 if the compiler used then # isn't gcc; configure determines that. WARN_CFLAGS will be either
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor