[LLVMdev] gfortran: array constructor problems

Michael McCracken michael.mccracken at gmail.com
Tue Sep 5 11:53:20 PDT 2006

Hi, in order to get a handle on the questions in Chris's previous
email, I rebuilt LLVM with debugging info, and then rebuilt gcc4 with

In the process, I ran into an assertion error when compiling the first
part of libgfortran:

../../src/gcc/llvm-convert.cpp:3871: failed assertion
`(TREE_CONSTANT(exp) || TREE_CODE(exp) == STRING_CST) && "Isn't a

In this case, TreeConstantToLLVM::Convert() is getting a constant to
convert that fails the test "TREE_CONSTANT(exp)"
(from my gdb session:)

>Breakpoint 2, TreeConstantToLLVM::Convert (exp=0x45e48c60) at
>2: exp->common.constant_flag = 0
>1: exp->common.code = CONSTRUCTOR

>From the backtrace the problem,  calls ConvertArrayCONSTRUCTOR:

(gdb) bt
#0  0x9004802c in kill ()
#1  0x9012dfb4 in abort ()
#2  0x94af90b0 in __eprintf ()
#3  0x0029450c in TreeConstantToLLVM::Convert (exp=0x0) at
#4  0x00295d80 in TreeConstantToLLVM::ConvertArrayCONSTRUCTOR
(exp=0x45e48d20) at ../../src/gcc/llvm-convert.cpp:4083
#5  0x0028b624 in emit_global_to_llvm (decl=0x45e4c700) at
#6  0x00284844 in rest_of_decl_compilation (decl=0x45e4c700,
top_level=0, at_end=0) at ../../src/gcc/passes.c:252
#7  0x002a7da8 in TreeToLLVM::EmitBIND_EXPR (this=0xbfffe63c,
exp=0x45e4d5a0, DestLoc=0x0) at ../../src/gcc/llvm-convert.cpp:1119
#8  0x00297ac0 in TreeToLLVM::Emit (this=0xbfffe63c, exp=0x45e4d5a0,
DestLoc=0x0) at ../../src/gcc/llvm-convert.cpp:474
#9  0x002882f0 in llvm_emit_code_for_current_function
(fndecl=0x45e4ae00) at ../../src/gcc/llvm-backend.cpp:309

It is compiling libgfortran/intrinsics/selected_int_kind.f90, which
has only one array constructor, shown below. (this part is actually
generated at build time as selected_int_kind.inc)

 type :: int_info
    integer :: kind
    integer :: range
  end type int_info
  integer, parameter :: c = 4
  type (int_info), parameter :: int_infos(c) = (/ &
    int_info (1, range(0_1)), &
    int_info (2, range(0_2)), &
    int_info (4, range(0_4)), &
    int_info (8, range(0_8)) /)

This is trying to declare a constant array of int_info structures.
range() is an intrinsic function that returns the expoent range of the
argument's type kind. I haven't quite been able to figure out where
that gets evaluated, but I am pretty sure it should be a constant at
compile time.

Here's the output of debug_tree() for the expression that breaks the assertion:

Breakpoint 2, TreeConstantToLLVM::Convert (exp=0x45e48c60) at
2: exp->common.constant_flag = 0
1: debug_tree (exp) =  <constructor 0x45e48c60
    type <record_type 0x45e4c180 int_info BLK
        size <integer_cst 0x45e23870 constant invariant 64>
        unit size <integer_cst 0x45e238a0 constant invariant 8>
        align 32 symtab 1183925312 alias set -1
        fields <field_decl 0x45e4c200 kind type <integer_type 0x45e28480 int4>
            asm-frame-size 0 SI file
line 22
            size <integer_cst 0x45e23600 constant invariant 32>
            unit size <integer_cst 0x45e23120 constant invariant 4>
            align 32 offset_align 128
            offset <integer_cst 0x45e23150 constant invariant 0>
            bit offset <integer_cst 0x45e23c60 constant invariant 0>
context <record_type 0x45e4c180 int_info> arguments <integer_cst
0x45e23150 0>
            LLVM: uint 0 chain <field_decl 0x45e4c280 range>>
        pointer_to_this <pointer_type 0x45e4c580> chain <type_decl
0x45e4c300 D.269>>

    arg 0 <tree_list 0x45e49840 purpose <field_decl 0x45e4c200 kind>
        value <integer_cst 0x45e23db0 constant invariant 1>
        chain <tree_list 0x45e49860 purpose <field_decl 0x45e4c280
range> value <integer_cst 0x45e23db0 1>>>>

I'm having a hard time mapping this output to what I expected from the
structure, but that may be my inexperience with gcc internals.

For how to fix this, it seems like the problem here is in
gfc_conv_array_initializer() (trans-array.c:2905) , where
gfc_conv_structure() is called for EXPR_STRUCTURES in an array
initializer, even if it should be constant, and gfc_conv_structure()
doesn't set the constant_flag of the expression. My first guess is
that we might need to either relax the assertion (not sure what
problems that would cause), find a way to communicate that the
structure is intended to be contained in a constant array, or set the
structure as constant after we get it back in

I'm not entirely sure how to proceed here, so any advice would be appreciated.


Michael McCracken
UCSD CSE PhD Candidate
research: http://www.cse.ucsd.edu/~mmccrack/
misc: http://michael-mccracken.net/wp/

More information about the llvm-dev mailing list