aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c42
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/string1.C7
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;
+}
+