diff options
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/string1.C | 7 |
4 files changed, 45 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af163dd..24731c4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2006-07-18 Mark Mitchell <mark@codesourcery.com> + PR c++/28337 + * typeck.c (build_binary_op): Short-circuit pointer arithmetic in + templates. + +2006-07-18 Mark Mitchell <mark@codesourcery.com> + PR c++/28048 * semantics.c (check_accessibility_of_qualified_id): Robustify. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6661474..0ded718 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3043,16 +3043,6 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, switch (code) { - case PLUS_EXPR: - /* Handle the pointer + int case. */ - if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return cp_pointer_int_sum (PLUS_EXPR, op0, op1); - else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - return cp_pointer_int_sum (PLUS_EXPR, op1, op0); - else - common = 1; - break; - case MINUS_EXPR: /* Subtraction of two similar pointers. We must subtract them as integers, then divide by object size. */ @@ -3060,11 +3050,33 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), TREE_TYPE (type1))) return pointer_diff (op0, op1, common_type (type0, type1)); - /* Handle pointer minus int. Just like pointer plus int. */ - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return cp_pointer_int_sum (MINUS_EXPR, op0, op1); - else - common = 1; + /* In all other cases except pointer - int, the usual arithmetic + rules aply. */ + else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE)) + { + common = 1; + break; + } + /* The pointer - int case is just like pointer + int; fall + through. */ + case PLUS_EXPR: + if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE) + && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE)) + { + tree ptr_operand; + tree int_operand; + ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1); + int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1); + if (processing_template_decl) + { + result_type = TREE_TYPE (ptr_operand); + break; + } + return cp_pointer_int_sum (code, + ptr_operand, + int_operand); + } + common = 1; break; case MULT_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5e5470d..7fef270 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2006-07-18 Mark Mitchell <mark@codesourcery.com> + PR c++/28337 + * g++.dg/template/string1.C: New test. + +2006-07-18 Mark Mitchell <mark@codesourcery.com> + PR c++/28048 * g++.dg/template/defarg9.C: New test. diff --git a/gcc/testsuite/g++.dg/template/string1.C b/gcc/testsuite/g++.dg/template/string1.C new file mode 100644 index 0000000..a5d6c7d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/string1.C @@ -0,0 +1,7 @@ +// PR c++/28337 + +template <int> void foo() +{ + (0 ? "" : "X") + 1; +} + |