Bug 98487 - ICE: tree check: expected identifier_node, have tree_list in is_attribute_p, at attribs.h:155 [C2X or C++11 attribute syntax, gnu::format and -Wsuggest-attribute=format] or a suggest warning (release checking)
Summary: ICE: tree check: expected identifier_node, have tree_list in is_attribute_p, ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: 12.3
Assignee: Marek Polacek
URL:
Keywords: diagnostic, ice-checking, ice-on-valid-code
: 107802 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-12-31 09:20 UTC by Pekka S
Modified: 2022-12-19 16:51 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 12.2.1
Known to fail: 12.2.0
Last reconfirmed: 2021-11-25 00:00:00


Attachments
Triggers the ICE. (305 bytes, text/plain)
2020-12-31 09:20 UTC, Pekka S
Details
Possible patch (332 bytes, patch)
2020-12-31 09:21 UTC, Pekka S
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pekka S 2020-12-31 09:20:13 UTC
Created attachment 49862 [details]
Triggers the ICE.

Hi.

Combining C2X attribute syntax ``[[]]'', gnu::format and -Wsuggest-attribute=format seems to ICE.

This problem does not occur if a) ``__attribute__'' syntax is used instead, b) -Wsuggest-attribute=format is not used.  Does not happen when processing function declarations or if the corresponding library call is not present.

Only ``format(printf, ...)'' and ``format(scanf, ...)'' seem to be affected.


Attached test case.  Using GCC 11.0.0 20201231, aarch64-*-* on x86_64-w64-mingw32 but I presume this is not host or target related.


Given e.g. PR90953 and PR94733 I presume the problematic line is at:

gcc/c-family/c-format.c:1216:
1216                 if (is_attribute_p ("format", TREE_PURPOSE (c))

and it should use` get_attribute_name' instead.  Attached a patch that does just that.  Seems to fix the problem, but I'm no expert on GCC internals.


$ cat attribute__format.c [excerpt]
#define ATTR(...) [[gnu::__VA_ARGS__]]
// ...
ATTR(__format__(__printf__, 1, 2))
void
do_printf(const char * const a0, ...) { /* ... */ }

$ gcc -c -std=c2x -Wall -Wextra -Wpedantic -Wsuggest-attribute=format attribute__format.c

attribute__format.c: In function 'do_printf':
attribute__format.c:17:3: internal compiler error: tree check: expected identifier_node, have tree_list in is_attribute_p, at attribs.h:155
   17 |   vprintf(a0, ap);
      |   ^~~~~~~

$ gcc -c -std=c2x -Wall -Wextra -Wpedantic -Wsuggest-attribute=format -wrapper gdb,--args
(gdb) b internal_error
(gdb) run
Thread 1 hit Breakpoint 1, internal_error (
    gmsgid=0x1cc3f90 <(anonymous namespace)::pass_data_vrp+2000> "tree check: %s, have %s in %s, at %s:%d")
    at <...>/gcc/gcc/diagnostic.c:1764
(gdb) bt
#0  internal_error (
    gmsgid=0x1cc3f90 <(anonymous namespace)::pass_data_vrp+2000> "tree check: %s, have %s in %s, at %s:%d")
    at <...>/gcc/gcc/diagnostic.c:1764
#1  0x0000000001a9adf2 in tree_check_failed (node=<optimized out>,
    file=0x1bc8580 <type_suffix(tree_node*)::suffixes+1312> "<...>/gcc/gcc/attribs.h",
    line=<optimized out>, function=0x1bc856d <type_suffix(tree_node*)::suffixes+1293> "is_attribute_p")
    at <...>/gcc/gcc/tree.c:13438
#2  0x0000000001921e1a in tree_check (__c=<optimized out>, __g=<optimized out>, __l=<optimized out>,
    __f=<optimized out>, __t=<optimized out>) at <...>/gcc/gcc/tree.h:3594
#3  is_attribute_p (ident=0x1cc3f90 <(anonymous namespace)::pass_data_vrp+2000>,
    attr_name=0x1bc90fd <type_suffix(tree_node*)::suffixes+4253> "format")
    at <...>/gcc/gcc/attribs.h:155
#4  0x00000000019228d6 in is_attribute_p (attr_name=0x1bc90fd <type_suffix(tree_node*)::suffixes+4253> "format",
    ident=<optimized out>) at <...>/gcc/gcc/tree.h:3452
#5  check_function_format (fntype=fntype@entry=0x1eea39d8, attrs=<optimized out>, nargs=nargs@entry=2,
    argarray=argarray@entry=0x1edf9e40, arglocs=arglocs@entry=0x1ad0e878)
    at <...>/gcc/gcc/c-family/c-format.c:1216
#6  0x00000000004cbea6 in check_function_arguments (loc=loc@entry=34268454, fndecl=fndecl@entry=0x1ec0b900,
    fntype=fntype@entry=0x1eea39d8, nargs=<optimized out>, nargs@entry=2, argarray=argarray@entry=0x1edf9e40,
    arglocs=arglocs@entry=0x1ad0e878) at <...>/gcc/gcc/tree.h:3718
#7  0x000000000044c701 in build_function_call_vec (loc=<optimized out>, loc@entry=34268454, arg_loc=arg_loc@entry=...,
    function=<optimized out>, function@entry=0x1ec0b900, params=<optimized out>, origtypes=<optimized out>,
    origtypes@entry=0x1eeddb90, orig_fundecl=0x1ec0b900, orig_fundecl@entry=0x0)
    at <...>/gcc/gcc/c/c-typeck.c:3144
#8  0x000000000044d4fa in c_build_function_call_vec (loc=loc@entry=34268454, arg_loc=...,
    function=function@entry=0x1ec0b900, params=<optimized out>, params@entry=0x1edf9e38, origtypes=0x1eeddb90)
    at <...>/gcc/gcc/c/c-typeck.c:3210
#9  0x000000000046ea76 in c_parser_postfix_expression_after_primary (parser=parser@entry=0x1ead4240,
    expr_loc=expr_loc@entry=34268454, expr=...) at <...>/gcc/gcc/c/c-parser.c:10469
#10 0x0000000000465724 in c_parser_postfix_expression (parser=<optimized out>, parser@entry=0x1ead4240)
    at <...>/gcc/gcc/../libcpp/include/line-map.h:577
#11 0x0000000000469fdb in c_parser_unary_expression (parser=parser@entry=0x1ead4240)
    at <...>/gcc/gcc/c/c-parser.c:8230
#12 0x000000000046ba20 in c_parser_cast_expression (parser=parser@entry=0x1ead4240, after=after@entry=0x0)
    at <...>/gcc/gcc/c/c-parser.c:8072
#13 0x000000000046bcf6 in c_parser_binary_expression (parser=parser@entry=0x1ead4240, after=0x0, omp_atomic_lhs=0x0)
    at <...>/gcc/gcc/c/c-parser.c:7875
#14 0x000000000046d09e in c_parser_conditional_expression (parser=parser@entry=0x1ead4240, after=<optimized out>,
    omp_atomic_lhs=<optimized out>) at <...>/gcc/gcc/c/c-parser.c:7598
#15 0x000000000046d7c9 in c_parser_expr_no_commas (parser=parser@entry=0x1ead4240, after=after@entry=0x0,
    omp_atomic_lhs=omp_atomic_lhs@entry=0x0) at <...>/gcc/gcc/c/c-parser.c:7513
#16 0x000000000046da8d in c_parser_expression (parser=parser@entry=0x1ead4240)
    at <...>/gcc/gcc/c/c-parser.c:10606
#17 0x000000000046e34a in c_parser_expression_conv (parser=0x1ead4240)
    at <...>/gcc/gcc/c/c-parser.c:10645
#18 0x0000000000462b14 in c_parser_statement_after_labels (parser=parser@entry=0x1ead4240, if_p=if_p@entry=0x0,
    chain=chain@entry=0x0) at <...>/gcc/gcc/c/c-parser.c:6249
#19 0x0000000000465228 in c_parser_compound_statement_nostart (parser=parser@entry=0x1ead4240)
    at <...>/gcc/gcc/c/c-parser.c:5788
#20 0x00000000004850cb in c_parser_compound_statement (parser=parser@entry=0x1ead4240,
    endlocp=endlocp@entry=0x1ad0f990) at <...>/gcc/gcc/c/c-parser.c:5597
#21 0x0000000000486d9b in c_parser_declaration_or_fndef (parser=0x1ead4240, fndef_ok=<optimized out>,
    static_assert_ok=<optimized out>, empty_ok=<optimized out>, nested=<optimized out>, start_attr_ok=<optimized out>,
    objc_foreach_object_declaration=<optimized out>, omp_declare_simd_clauses=..., have_attrs=<optimized out>,
    attrs=<optimized out>, oacc_routine_data=<optimized out>, fallthru_attr_p=<optimized out>)
    at <...>/gcc/gcc/c/c-parser.c:2539
#22 0x000000000048f97e in c_parser_external_declaration (parser=0x1ead4240)
    at <...>/gcc/gcc/c/c-parser.c:1777
#23 0x000000000049053c in c_parser_translation_unit (parser=<optimized out>)
    at <...>/gcc/gcc/c/c-parser.c:1650
#24 c_parse_file () at <...>/gcc/gcc/c/c-parser.c:21935
#25 0x00000000004f74ff in c_common_parse_file () at <...>/gcc/gcc/c-family/c-opts.c:1211
#26 0x0000000000a11bd2 in compile_file () at <...>/gcc/gcc/toplev.c:457
#27 0x0000000001a08d58 in do_compile () at <...>/gcc/gcc/toplev.c:2193
#28 toplev::main (this=this@entry=0x1ad0fe0e, argc=<optimized out>, argc@entry=21, argv=<optimized out>,
    argv@entry=0x1e25f0) at <...>/gcc/gcc/toplev.c:2332
#29 0x0000000001b70737 in main (argc=21, argv=0x1e25f0) at <...>/gcc/gcc/main.c:39
Comment 1 Pekka S 2020-12-31 09:21:03 UTC
Created attachment 49863 [details]
Possible patch

Uses get_attribute_name instead of TREE_PURPOSE.
Comment 2 Andrew Pinski 2021-11-25 23:19:15 UTC
Confirmed.
Simplier testcase:
#include <stdarg.h>


[[gnu::__format__(__printf__, 1, 2)]]
void
do_printf(const char * const a0, ...)
  {
  va_list ap;
  va_start(ap, a0);
  __builtin_vprintf(a0, ap);
  va_end(ap);
  }

[[gnu::__format__(__scanf__, 1, 2)]]
void
do_scanf(const char * const a0, ...)
  {
  va_list ap;
  va_start(ap, a0);
  __builtin_vscanf(a0, ap);
  va_end(ap);
  }

[[gnu::__format__(__strftime__, 1, 0)]]
void
do_strftime(const char * const a0, struct tm * a1)
  {
  char buff[256];
  __builtin_strftime(buff, sizeof(buff), a0, a1);
  puts(buff);
  }
Comment 3 Andrew Pinski 2022-11-22 19:17:55 UTC
*** Bug 107802 has been marked as a duplicate of this bug. ***
Comment 4 Andrew Pinski 2022-11-22 19:18:36 UTC
Without checking enabled, we get a suggest warning too which is wrong.
Comment 5 Andrew Pinski 2022-11-22 19:25:04 UTC
I should note this happens with both front-ends too. though the code is shared here.
Comment 6 GCC Commits 2022-12-19 16:43:54 UTC
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:68e51bd0a85794cd437d3e740357dfef84dc560d

commit r13-4796-g68e51bd0a85794cd437d3e740357dfef84dc560d
Author: Marek Polacek <polacek@redhat.com>
Date:   Fri Dec 16 12:28:43 2022 -0500

    c-family: Fix ICE with -Wsuggest-attribute [PR98487]
    
    Here we crash because check_function_format was using TREE_PURPOSE
    directly rather than using get_attribute_name.
    
            PR c/98487
    
    gcc/c-family/ChangeLog:
    
            * c-format.cc (check_function_format): Use get_attribute_name.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/Wsuggest-attribute-1.c: New test.
Comment 7 GCC Commits 2022-12-19 16:49:37 UTC
The releases/gcc-12 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:0e345504ec9349d9a3bf826c3e16b7e973739485

commit r12-8993-g0e345504ec9349d9a3bf826c3e16b7e973739485
Author: Marek Polacek <polacek@redhat.com>
Date:   Fri Dec 16 12:28:43 2022 -0500

    c-family: Fix ICE with -Wsuggest-attribute [PR98487]
    
    Here we crash because check_function_format was using TREE_PURPOSE
    directly rather than using get_attribute_name.
    
            PR c/98487
    
    gcc/c-family/ChangeLog:
    
            * c-format.cc (check_function_format): Use get_attribute_name.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/Wsuggest-attribute-1.c: New test.
    
    (cherry picked from commit 68e51bd0a85794cd437d3e740357dfef84dc560d)
Comment 8 Marek Polacek 2022-12-19 16:50:18 UTC
Fixed for GCC 13 and 12.3.