aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-06-04 15:56:57 -0400
committerJason Merrill <jason@redhat.com>2020-06-05 13:54:54 -0400
commit5094c4400a8687dcf44f5993aee3a88e98519f3b (patch)
treee55070d15ade1137ed75162bab35f98e04a91825 /gcc
parent640e05e02b567fa5ccf4c207e6fc6c3e9a93b17c (diff)
downloadgcc-5094c4400a8687dcf44f5993aee3a88e98519f3b.zip
gcc-5094c4400a8687dcf44f5993aee3a88e98519f3b.tar.gz
gcc-5094c4400a8687dcf44f5993aee3a88e98519f3b.tar.bz2
c++: Fix pretty-print of pointer minus integer.
For whatever reason, GCC internally represents a pointer minus an integer as a pointer plus a very large unsigned integer. But exposing that to users is unsightly, and it's easy enough to show the real value. gcc/cp/ChangeLog: * error.c (dump_binary_op): Handle negative operand to POINTER_PLUS_EXPR. gcc/c-family/ChangeLog: * c-pretty-print.c (pp_c_additive_expression): Handle negative operand to POINTER_PLUS_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-ptrsub2.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-pretty-print.c11
-rw-r--r--gcc/cp/error.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub2.C4
3 files changed, 22 insertions, 2 deletions
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 32f30f2..71baf5e 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -1898,7 +1898,16 @@ pp_c_additive_expression (c_pretty_printer *pp, tree e)
else
pp_minus (pp);
pp_c_whitespace (pp);
- pp->multiplicative_expression (TREE_OPERAND (e, 1));
+ {
+ tree op1 = TREE_OPERAND (e, 1);
+ if (code == POINTER_PLUS_EXPR
+ && TREE_CODE (op1) == INTEGER_CST
+ && tree_int_cst_sign_bit (op1))
+ /* A pointer minus an integer is represented internally as plus a very
+ large number, don't expose that to users. */
+ op1 = convert (ssizetype, op1);
+ pp->multiplicative_expression (op1);
+ }
break;
default:
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 46970f9..0d6375e 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2909,7 +2909,14 @@ dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
else
pp_string (pp, M_("<unknown operator>"));
pp_cxx_whitespace (pp);
- dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ tree op1 = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == POINTER_PLUS_EXPR
+ && TREE_CODE (op1) == INTEGER_CST
+ && tree_int_cst_sign_bit (op1))
+ /* A pointer minus an integer is represented internally as plus a very
+ large number, don't expose that to users. */
+ op1 = convert (ssizetype, op1);
+ dump_expr (pp, op1, flags | TFF_EXPR_IN_PARENS);
pp_cxx_right_paren (pp);
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub2.C
new file mode 100644
index 0000000..fd644ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub2.C
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+
+char c;
+constexpr char p2 = *(&c - 1); // { dg-error "-1" }