From 0225a19df7763f213bc16792b91d9cfdd153a5e4 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 19 Jul 2006 17:32:38 +0000 Subject: [PATCH] re PR c++/28337 (ICE with string literals in templates) PR c++/28337 * typeck.c (build_binary_op): Short-circuit pointer arithmetic in templates. PR c++/28337 * g++.dg/template/string1.C: New test. From-SVN: r115597 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/typeck.c | 42 ++++++++++++++++--------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/string1.C | 7 +++++ 4 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/string1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af163dd644e..24731c4bbb1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2006-07-18 Mark Mitchell + + PR c++/28337 + * typeck.c (build_binary_op): Short-circuit pointer arithmetic in + templates. + 2006-07-18 Mark Mitchell PR c++/28048 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6661474a9fb..0ded718d4bb 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 5e5470d266d..7fef2708796 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-07-18 Mark Mitchell + + PR c++/28337 + * g++.dg/template/string1.C: New test. + 2006-07-18 Mark Mitchell PR c++/28048 diff --git a/gcc/testsuite/g++.dg/template/string1.C b/gcc/testsuite/g++.dg/template/string1.C new file mode 100644 index 00000000000..a5d6c7dd60f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/string1.C @@ -0,0 +1,7 @@ +// PR c++/28337 + +template void foo() +{ + (0 ? "" : "X") + 1; +} +