[Bug analyzer/105092] ICE with local with NULL DECL_CONTEXT on templatized OpenMP iterator

dmalcolm at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Mar 29 13:56:03 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105092

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at redhat dot com,
                   |                            |jason at redhat dot com
            Summary|ICE in                      |ICE with local with NULL
                   |get_region_for_local, at    |DECL_CONTEXT on templatized
                   |analyzer/region.cc:874      |OpenMP iterator
             Status|NEW                         |WAITING

--- Comment #2 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
The root cause of PR analyzer/104979 involved looking up a local variable in
the wrong stack frame, so in r12-7790-g4cebae0924248beb I added assertions to
the analyzer to ensure that when accessing a local variable in a frame, the
frame is for the correct function.

This new assertion is failing on the templatizing OpenMP reproducer in
ana::frame_region::get_region_for_local:

869             case SSA_NAME:
870               {
871                 if (tree var = SSA_NAME_VAR (expr))
872                   {
873                     if (DECL_P (var))
874                       gcc_assert (DECL_CONTEXT (var) == m_fun->decl);
875                   }

on this gimple stmt:
  i_11 = 0;

The SSA name's underlying var_decl "i" has NULL for its DECL_CONTEXT, despite
appearing to be a local variable.

"i" is created here:

(gdb) bt
#0  copy_node (node=<var_decl 0x7fffea653d80 i>) at ../../src/gcc/tree.cc:1358
#1  0x0000000000bf64a3 in copy_decl (decl=<var_decl 0x7fffea653d80 i>) at
../../src/gcc/cp/lex.cc:1027
#2  0x0000000000d87d5c in tsubst_decl (t=<var_decl 0x7fffea653d80 i>,
args=<tree_vec 0x7fffea7d2700>, complain=3) at ../../src/gcc/cp/pt.cc:14912
#3  0x0000000000d9462f in tsubst_omp_clause_decl (decl=<tree_list
0x7fffea7db280>, args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >,
iterator_cache=0x7fffffffcc10) at ../../src/gcc/cp/pt.cc:17540
#4  0x0000000000d9509d in tsubst_omp_clauses (clauses=<omp_clause
0x7fffea7d3fc0>, ort=C_ORT_OMP, args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >) at
../../src/gcc/cp/pt.cc:17643
#5  0x0000000000d9eec5 in tsubst_expr (t=<omp_task 0x7fffea7db320>,
args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >,
integral_constant_expression_p=false) at ../../src/gcc/cp/pt.cc:18974
#6  0x0000000000d9d132 in tsubst_expr (t=<bind_expr 0x7fffea7d45a0>,
args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >,
integral_constant_expression_p=false) at ../../src/gcc/cp/pt.cc:18761
#7  0x0000000000d99d5c in tsubst_expr (t=<statement_list 0x7fffea7d2500>,
args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >,
integral_constant_expression_p=false) at ../../src/gcc/cp/pt.cc:18404
#8  0x0000000000d9d132 in tsubst_expr (t=<bind_expr 0x7fffea7d4570>,
args=<tree_vec 0x7fffea7d2700>, complain=3, 
    in_decl=<template_decl 0x7ffff7ffb480 __ct >,
integral_constant_expression_p=false) at ../../src/gcc/cp/pt.cc:18761
#9  0x0000000000dc340d in instantiate_body (pattern=<template_decl
0x7ffff7ffb480 __ct >, args=<tree_vec 0x7fffea7d2700>, 
    d=<function_decl 0x7fffea7c4f00 __ct >, nested_p=false) at
../../src/gcc/cp/pt.cc:26338
#10 0x0000000000dc4fcf in instantiate_decl (d=<function_decl 0x7fffea7c4f00
__ct >, defer_ok=false, expl_inst_class_mem_p=false)
    at ../../src/gcc/cp/pt.cc:26630
#11 0x0000000000dc53bb in instantiate_pending_templates (retries=0) at
../../src/gcc/cp/pt.cc:26709
#12 0x0000000000ba2148 in c_parse_final_cleanups () at
../../src/gcc/cp/decl2.cc:5092
#13 0x0000000000f31e7a in c_common_parse_file () at
../../src/gcc/c-family/c-opts.cc:1262
#14 0x00000000014ef80a in compile_file () at ../../src/gcc/toplev.cc:452
#15 0x0000000000a20e98 in do_compile (no_backend=false) at
../../src/gcc/toplev.cc:2168
#16 toplev::main (this=this@entry=0x7fffffffdcae, argc=<optimized out>,
argc@entry=25, argv=<optimized out>, argv@entry=0x7fffffffddb8)
    at ../../src/gcc/toplev.cc:2320
#17 0x0000000000a22dd5 in main (argc=25, argv=0x7fffffffddb8) at
../../src/gcc/main.cc:39

as a copy of the "i" created here:

(gdb) bt
#0  make_node (code=VAR_DECL) at ../../src/gcc/tree.cc:1211
#1  0x00000000017e2d6e in build_decl (loc=292864, code=VAR_DECL,
name=<identifier_node 0x7fffea7d3d80 i>, type=<integer_type 0x7fffea6655e8
int>)
    at ../../src/gcc/tree.cc:5289
#2  0x0000000000d0c3ce in cp_parser_omp_iterators (parser=0x7fffea6747b8) at
../../src/gcc/cp/parser.cc:39118
#3  0x0000000000d0c746 in cp_parser_omp_clause_affinity (parser=0x7fffea6747b8,
list=<tree 0x0>) at ../../src/gcc/cp/parser.cc:39181
#4  0x0000000000d0f6b5 in cp_parser_omp_all_clauses (parser=0x7fffea6747b8,
mask=..., where=0x259c622 "#pragma omp task", 
    pragma_tok=0x7fffea5b41c8, finish_p=true, nested=0) at
../../src/gcc/cp/parser.cc:40274
#5  0x0000000000d1c848 in cp_parser_omp_task (parser=0x7fffea6747b8,
pragma_tok=0x7fffea5b41c8, if_p=0x0) at ../../src/gcc/cp/parser.cc:43585
#6  0x0000000000d307ba in cp_parser_omp_construct (parser=0x7fffea6747b8,
pragma_tok=0x7fffea5b41c8, if_p=0x0) at ../../src/gcc/cp/parser.cc:47225
#7  0x0000000000d31980 in cp_parser_pragma (parser=0x7fffea6747b8,
context=pragma_compound, if_p=0x0) at ../../src/gcc/cp/parser.cc:47866
#8  0x0000000000cd0ee5 in cp_parser_statement (parser=0x7fffea6747b8,
in_statement_expr=<tree 0x0>, in_compound=true, if_p=0x0, chain=0x0, 
    loc_after_labels=0x0) at ../../src/gcc/cp/parser.cc:12393
#9  0x0000000000cd1f60 in cp_parser_statement_seq_opt (parser=0x7fffea6747b8,
in_statement_expr=<tree 0x0>) at ../../src/gcc/cp/parser.cc:12846
#10 0x0000000000cd1e50 in cp_parser_compound_statement (parser=0x7fffea6747b8,
in_statement_expr=<tree 0x0>, bcs_flags=0, function_body=true)
    at ../../src/gcc/cp/parser.cc:12798
#11 0x0000000000cebffb in cp_parser_function_body (parser=0x7fffea6747b8,
in_function_try_block=false) at ../../src/gcc/cp/parser.cc:25056
#12 0x0000000000cec382 in cp_parser_ctor_initializer_opt_and_function_body
(parser=0x7fffea6747b8, in_function_try_block=false)
    at ../../src/gcc/cp/parser.cc:25107
#13 0x0000000000cf95bb in cp_parser_function_definition_after_declarator
(parser=0x7fffea6747b8, inline_p=true) at ../../src/gcc/cp/parser.cc:31237
#14 0x0000000000cfc4b6 in cp_parser_late_parsing_for_member
(parser=0x7fffea6747b8, member_function=<function_decl 0x7fffea7c4d00 __ct >)
    at ../../src/gcc/cp/parser.cc:32159
#15 0x0000000000cef1f0 in cp_parser_class_specifier_1 (parser=0x7fffea6747b8)
at ../../src/gcc/cp/parser.cc:26170
#16 0x0000000000cef2ec in cp_parser_class_specifier (parser=0x7fffea6747b8) at
../../src/gcc/cp/parser.cc:26198
#17 0x0000000000cdf767 in cp_parser_type_specifier (parser=0x7fffea6747b8,
flags=33, decl_specs=0x7fffffffd820, is_declaration=true, 
    declares_class_or_enum=0x7fffffffd77c, is_cv_qualifier=0x7fffffffd77b) at
../../src/gcc/cp/parser.cc:19342
#18 0x0000000000cd9513 in cp_parser_decl_specifier_seq (parser=0x7fffea6747b8,
flags=33, decl_specs=0x7fffffffd820, 
    declares_class_or_enum=0x7fffffffd8c4) at ../../src/gcc/cp/parser.cc:15901
#19 0x0000000000cfaa94 in cp_parser_single_declaration (parser=0x7fffea6747b8,
checks=0x0, member_p=false, explicit_specialization_p=false, 
    friend_p=0x7fffffffd917) at ../../src/gcc/cp/parser.cc:31642
#20 0x0000000000cf984a in cp_parser_template_declaration_after_parameters
(parser=0x7fffea6747b8, parameter_list=<tree_vec 0x7fffea7d22a0>, 
    member_p=false) at ../../src/gcc/cp/parser.cc:31305
#21 0x0000000000cfa909 in cp_parser_explicit_template_declaration
(parser=0x7fffea6747b8, member_p=false) at ../../src/gcc/cp/parser.cc:31571
#22 0x0000000000cfa967 in cp_parser_template_declaration_after_export
(parser=0x7fffea6747b8, member_p=false) at ../../src/gcc/cp/parser.cc:31590
#23 0x0000000000cdbff0 in cp_parser_template_declaration
(parser=0x7fffea6747b8, member_p=false) at ../../src/gcc/cp/parser.cc:17452
#24 0x0000000000cd7323 in cp_parser_declaration (parser=0x7fffea6747b8,
prefix_attrs=<tree 0x0>) at ../../src/gcc/cp/parser.cc:14893
#25 0x0000000000cd770d in cp_parser_toplevel_declaration
(parser=0x7fffea6747b8) at ../../src/gcc/cp/parser.cc:14983
#26 0x0000000000cbf9fc in cp_parser_translation_unit (parser=0x7fffea6747b8) at
../../src/gcc/cp/parser.cc:5010
#27 0x0000000000d31f14 in c_parse_file () at ../../src/gcc/cp/parser.cc:48046
#28 0x0000000000f31d90 in c_common_parse_file () at
../../src/gcc/c-family/c-opts.cc:1240
#29 0x00000000014ef80a in compile_file () at ../../src/gcc/toplev.cc:452
#30 0x0000000000a20e98 in do_compile (no_backend=false) at
../../src/gcc/toplev.cc:2168
#31 toplev::main (this=this@entry=0x7fffffffdcae, argc=<optimized out>,
argc@entry=25, argv=<optimized out>, argv@entry=0x7fffffffddb8)
    at ../../src/gcc/toplev.cc:2320
#32 0x0000000000a22dd5 in main (argc=25, argv=0x7fffffffddb8) at
../../src/gcc/main.cc:39

which has context: <function_decl 0x7fffea7c4d00 __ct >

The copy of "i" initially has the same context after copy_decl in tsubst_decl
here:

Run till exit from #0  0x0000000000bf64a3 in copy_decl (decl=<var_decl
0x7fffea653d80 i>) at ../../src/gcc/cp/lex.cc:1027
tsubst_decl (t=<var_decl 0x7fffea653d80 i>, args=<tree_vec 0x7fffea7d2700>,
complain=3) at ../../src/gcc/cp/pt.cc:14912
14912           r = copy_decl (t);

but later in tsubst_decl it gets overwritten here:

14982           DECL_CONTEXT (r) = ctx;

where "ctx" is NULL.  ctx was set to NULL was set in tsubst_decl earlier here:

14865               if (!(VAR_P (t) && DECL_LOCAL_DECL_P (t)))
14866                 /* Subsequent calls to pushdecl will fill this in.  */
14867                 ctx = NULL_TREE;

and ctxt remains NULL until the overwrite of DECL_CONTEXT (r).

I'm not quite sure what the expected interaction between C++ template
substitution and the OMP code here is.

Is it expected that every local var_decl has a non-NULL DECL_CONTEXT?
Alternatively, how should the analyzer determine which variables should be on
the stack, and, of those, which function they relate to?

Sorry if I'm missing something here.


More information about the Gcc-bugs mailing list