Bug 89495 - [9 Regression] gcc/c-family/c-format.c:1272:20: runtime error: signed integer overflow: 214748365 * 10 cannot be represented in type 'int'
Summary: [9 Regression] gcc/c-family/c-format.c:1272:20: runtime error: signed integer...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 9.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 86137 (view as bug list)
Depends on:
Blocks: ubsan
  Show dependency treegraph
 
Reported: 2019-02-25 14:23 UTC by Martin Liška
Modified: 2021-09-20 02:05 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 8.2.0
Known to fail: 9.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liška 2019-02-25 14:23:55 UTC
It's a recent UBSAN error:

$ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/tree-ssa/builtin-printf-warn-2.c -O -Wformat -Wformat-overflow=2 -ftrack-macro-expansion=0 -W
../../gcc/c-family/c-format.c:1272:15: runtime error: signed integer overflow: 2147483640 + 8 cannot be represented in type 'int'
    #0 0xaeca84 in maybe_read_dollar_number ../../gcc/c-family/c-format.c:1272
    #1 0xaf28a1 in argument_parser::read_any_dollar() ../../gcc/c-family/c-format.c:2082
    #2 0xafd7c6 in check_format_info_main ../../gcc/c-family/c-format.c:2855
    #3 0xaf0b77 in check_format_arg ../../gcc/c-family/c-format.c:1748
    #4 0xab18f6 in check_function_arguments_recurse(void (*)(void*, tree_node*, unsigned long), void*, tree_node*, unsigned long) ../../gcc/c-family/c-common.c:5895
    #5 0xab1380 in check_function_arguments_recurse(void (*)(void*, tree_node*, unsigned long), void*, tree_node*, unsigned long) ../../gcc/c-family/c-common.c:5827
    #6 0xaedc92 in check_format_info ../../gcc/c-family/c-format.c:1471
    #7 0xaebc46 in check_function_format(tree_node const*, tree_node*, int, tree_node**, vec<unsigned int, va_heap, vl_ptr>*) ../../gcc/c-family/c-format.c:1128
    #8 0xab1020 in check_function_arguments(unsigned int, tree_node const*, tree_node const*, int, tree_node**, vec<unsigned int, va_heap, vl_ptr>*) ../../gcc/c-family/c-common.c:5802
    #9 0x92d079 in build_function_call_vec(unsigned int, vec<unsigned int, va_heap, vl_ptr>, tree_node*, vec<tree_node*, va_gc, vl_embed>*, vec<tree_node*, va_gc, vl_embed>*) ../../gcc/c/c-typeck.c:3118
    #10 0x92dfdc in c_build_function_call_vec(unsigned int, vec<unsigned int, va_heap, vl_ptr>, tree_node*, vec<tree_node*, va_gc, vl_embed>*, vec<tree_node*, va_gc, vl_embed>*) ../../gcc/c/c-typeck.c:3184
    #11 0x9db6b7 in c_parser_postfix_expression_after_primary ../../gcc/c/c-parser.c:9595
    #12 0x9d9511 in c_parser_postfix_expression ../../gcc/c/c-parser.c:9270
    #13 0x9cc738 in c_parser_unary_expression ../../gcc/c/c-parser.c:7383
    #14 0x9cb0b0 in c_parser_cast_expression ../../gcc/c/c-parser.c:7222
    #15 0x9c58c7 in c_parser_binary_expression ../../gcc/c/c-parser.c:7025
    #16 0x9c4a15 in c_parser_conditional_expression ../../gcc/c/c-parser.c:6759
    #17 0x9c4518 in c_parser_expr_no_commas ../../gcc/c/c-parser.c:6676
    #18 0x9dc1c6 in c_parser_expression ../../gcc/c/c-parser.c:9731
    #19 0x9dc6db in c_parser_expression_conv ../../gcc/c/c-parser.c:9764
    #20 0x9c0147 in c_parser_statement_after_labels ../../gcc/c/c-parser.c:5610
    #21 0x9be83e in c_parser_compound_statement_nostart ../../gcc/c/c-parser.c:5148
    #22 0x9bdf55 in c_parser_compound_statement ../../gcc/c/c-parser.c:4982
    #23 0x9b437c in c_parser_declaration_or_fndef ../../gcc/c/c-parser.c:2354
    #24 0x9b12a7 in c_parser_external_declaration ../../gcc/c/c-parser.c:1653
    #25 0x9b0aa4 in c_parser_translation_unit ../../gcc/c/c-parser.c:1534
    #26 0xa16edb in c_parse_file() ../../gcc/c/c-parser.c:19854
    #27 0xb39675 in c_common_parse_file() ../../gcc/c-family/c-opts.c:1155
    #28 0x1ffdeae in compile_file ../../gcc/toplev.c:456
    #29 0x2005afb in do_compile ../../gcc/toplev.c:2204
    #30 0x2006129 in toplev::main(int, char**) ../../gcc/toplev.c:2339
    #31 0x436822f in main ../../gcc/main.c:39
    #32 0x7ffff6e7bb7a in __libc_start_main ../csu/libc-start.c:308
    #33 0x857579 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x857579)

../../gcc/c-family/c-format.c:1272:20: runtime error: signed integer overflow: 214748365 * 10 cannot be represented in type 'int'
    #0 0xaeca29 in maybe_read_dollar_number ../../gcc/c-family/c-format.c:1272
    #1 0xaf28a1 in argument_parser::read_any_dollar() ../../gcc/c-family/c-format.c:2082
    #2 0xafd7c6 in check_format_info_main ../../gcc/c-family/c-format.c:2855
    #3 0xaf0b77 in check_format_arg ../../gcc/c-family/c-format.c:1748
    #4 0xab18f6 in check_function_arguments_recurse(void (*)(void*, tree_node*, unsigned long), void*, tree_node*, unsigned long) ../../gcc/c-family/c-common.c:5895
    #5 0xab1380 in check_function_arguments_recurse(void (*)(void*, tree_node*, unsigned long), void*, tree_node*, unsigned long) ../../gcc/c-family/c-common.c:5827
    #6 0xaedc92 in check_format_info ../../gcc/c-family/c-format.c:1471
    #7 0xaebc46 in check_function_format(tree_node const*, tree_node*, int, tree_node**, vec<unsigned int, va_heap, vl_ptr>*) ../../gcc/c-family/c-format.c:1128
    #8 0xab1020 in check_function_arguments(unsigned int, tree_node const*, tree_node const*, int, tree_node**, vec<unsigned int, va_heap, vl_ptr>*) ../../gcc/c-family/c-common.c:5802
    #9 0x92d079 in build_function_call_vec(unsigned int, vec<unsigned int, va_heap, vl_ptr>, tree_node*, vec<tree_node*, va_gc, vl_embed>*, vec<tree_node*, va_gc, vl_embed>*) ../../gcc/c/c-typeck.c:3118
    #10 0x92dfdc in c_build_function_call_vec(unsigned int, vec<unsigned int, va_heap, vl_ptr>, tree_node*, vec<tree_node*, va_gc, vl_embed>*, vec<tree_node*, va_gc, vl_embed>*) ../../gcc/c/c-typeck.c:3184
    #11 0x9db6b7 in c_parser_postfix_expression_after_primary ../../gcc/c/c-parser.c:9595
    #12 0x9d9511 in c_parser_postfix_expression ../../gcc/c/c-parser.c:9270
    #13 0x9cc738 in c_parser_unary_expression ../../gcc/c/c-parser.c:7383
    #14 0x9cb0b0 in c_parser_cast_expression ../../gcc/c/c-parser.c:7222
    #15 0x9c58c7 in c_parser_binary_expression ../../gcc/c/c-parser.c:7025
    #16 0x9c4a15 in c_parser_conditional_expression ../../gcc/c/c-parser.c:6759
    #17 0x9c4518 in c_parser_expr_no_commas ../../gcc/c/c-parser.c:6676
    #18 0x9dc1c6 in c_parser_expression ../../gcc/c/c-parser.c:9731
    #19 0x9dc6db in c_parser_expression_conv ../../gcc/c/c-parser.c:9764
    #20 0x9c0147 in c_parser_statement_after_labels ../../gcc/c/c-parser.c:5610
    #21 0x9be83e in c_parser_compound_statement_nostart ../../gcc/c/c-parser.c:5148
    #22 0x9bdf55 in c_parser_compound_statement ../../gcc/c/c-parser.c:4982
    #23 0x9b437c in c_parser_declaration_or_fndef ../../gcc/c/c-parser.c:2354
    #24 0x9b12a7 in c_parser_external_declaration ../../gcc/c/c-parser.c:1653
    #25 0x9b0aa4 in c_parser_translation_unit ../../gcc/c/c-parser.c:1534
    #26 0xa16edb in c_parse_file() ../../gcc/c/c-parser.c:19854
    #27 0xb39675 in c_common_parse_file() ../../gcc/c-family/c-opts.c:1155
    #28 0x1ffdeae in compile_file ../../gcc/toplev.c:456
    #29 0x2005afb in do_compile ../../gcc/toplev.c:2204
    #30 0x2006129 in toplev::main(int, char**) ../../gcc/toplev.c:2339
    #31 0x436822f in main ../../gcc/main.c:39
    #32 0x7ffff6e7bb7a in __libc_start_main ../csu/libc-start.c:308
    #33 0x857579 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x857579)
Comment 1 Jakub Jelinek 2019-02-25 15:30:47 UTC
Looks like a regression only because the test is new.
I see the same code in there e.g. in GCC 3.2.

That said, I think we can do something like:
2019-02-25  Jakub Jelinek  <jakub@redhat.com>

	PR c++/89495
	* c-format.c (maybe_read_dollar_number): Compute nargnum in
	HOST_WIDE_INT type to avoid overflows and change overflow_flag
	checking.

--- gcc/c-family/c-format.c.jj	2019-01-16 09:35:04.565323073 +0100
+++ gcc/c-family/c-format.c	2019-02-25 16:26:07.872810237 +0100
@@ -1268,9 +1268,9 @@ maybe_read_dollar_number (const char **f
   overflow_flag = 0;
   while (ISDIGIT (*fcp))
     {
-      int nargnum;
-      nargnum = 10 * argnum + (*fcp - '0');
-      if (nargnum < 0 || nargnum / 10 != argnum)
+      HOST_WIDE_INT nargnum
+	= HOST_WIDE_INT_UC (10) * argnum + (*fcp - '0');
+      if ((int) nargnum != nargnum)
 	overflow_flag = 1;
       argnum = nargnum;
       fcp++;
Comment 2 Jakub Jelinek 2019-02-25 23:44:22 UTC
Author: jakub
Date: Mon Feb 25 23:43:51 2019
New Revision: 269198

URL: https://gcc.gnu.org/viewcvs?rev=269198&root=gcc&view=rev
Log:
	PR c/89495
	* c-format.c (maybe_read_dollar_number): Compute nargnum in
	HOST_WIDE_INT type to avoid overflows and change overflow_flag
	checking.

Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-format.c
Comment 3 Jakub Jelinek 2019-02-25 23:48:40 UTC
Fixed.
Comment 4 Andrew Pinski 2021-09-20 02:05:21 UTC
*** Bug 86137 has been marked as a duplicate of this bug. ***