Bug 37738 - Fortran DW_TAG_common_block has incorrect placement/scope
Summary: Fortran DW_TAG_common_block has incorrect placement/scope
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.3.2
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on: 23057
Blocks:
  Show dependency treegraph
 
Reported: 2008-10-05 15:17 UTC by Jan Kratochvil
Modified: 2009-08-21 18:16 UTC (History)
3 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2008-10-06 15:11:07


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Kratochvil 2008-10-05 15:17:12 UTC
gfortran:
(1) Merges all common blocks into a single one.
(2) Places this single common block into the first subroutine where it was used.

Fix:
(1) The scope of the common block is only the subroutine where it is present.
    Each subroutine should have its own DW_TAG_common_block.
    Accessing variable imported by a common block in different subroutine does
    not access the common block - it creates a local variable there.
(2) (Placing the common block directly under CU not discussed - IMO wrong.)

Intel Fortran compiler IMO does it right.


subroutine a
  INTEGER*4 a_i
  common /block/a_i
  a_i = 1
end subroutine a
subroutine b
  INTEGER*4 b_i
  common /block/b_i
  a_i = 3
  b_i = 2
end subroutine b
subroutine c
  INTEGER*4 a_i
  common /block/a_i
  if (a_i .ne. 2) call abort
end subroutine c
program abc
  call a
  call b
  call c
end program abc


/opt/intel/fce/10.1.008/bin/ifort

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
 <1><68>: Abbrev Number: 3 (DW_TAG_subprogram)
  <2><8a>: Abbrev Number: 4 (DW_TAG_common_block)
   <3><a0>: Abbrev Number: 5 (DW_TAG_variable)
 <1><c8>: Abbrev Number: 3 (DW_TAG_subprogram)
  <2><ea>: Abbrev Number: 6 (DW_TAG_variable)
  <2><fa>: Abbrev Number: 4 (DW_TAG_common_block)
   <3><110>: Abbrev Number: 5 (DW_TAG_variable)
 <1><135>: Abbrev Number: 3 (DW_TAG_subprogram)
  <2><157>: Abbrev Number: 4 (DW_TAG_common_block)
   <3><16d>: Abbrev Number: 5 (DW_TAG_variable)
 <1><187>: Abbrev Number: 7 (DW_TAG_subprogram)

The section .debug_info contains:
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
     DW_AT_language    : 14     (Fortran 95)
     DW_AT_name        : abc.f90
     DW_AT_producer    : Intel (R) Fortran Compiler Fixes RangesRelative
 <1><68>: Abbrev Number: 3 (DW_TAG_subprogram)
     DW_AT_name        : a
 <2><8a>: Abbrev Number: 4 (DW_TAG_common_block)
     DW_AT_name        : block_
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <3><a0>: Abbrev Number: 5 (DW_TAG_variable)
     DW_AT_name        : a_i
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <1><c8>: Abbrev Number: 3 (DW_TAG_subprogram)
     DW_AT_name        : b
 <2><ea>: Abbrev Number: 6 (DW_TAG_variable)
     DW_AT_name        : a_i
     DW_AT_location    : 2 byte block: 76 70    (DW_OP_breg6: -16)
 <2><fa>: Abbrev Number: 4 (DW_TAG_common_block)
     DW_AT_name        : block_
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <3><110>: Abbrev Number: 5 (DW_TAG_variable)
     DW_AT_name        : b_i
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <1><135>: Abbrev Number: 3 (DW_TAG_subprogram)
     DW_AT_name        : c
 <2><157>: Abbrev Number: 4 (DW_TAG_common_block)
     DW_AT_name        : block_
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <3><16d>: Abbrev Number: 5 (DW_TAG_variable)
     DW_AT_name        : a_i
     DW_AT_location    : 9 byte block: 3 70 45 68 0 0 0 0 0     (DW_OP_addr: 684570)
 <1><187>: Abbrev Number: 7 (DW_TAG_subprogram)
     DW_AT_calling_convention: 2        (program)
     DW_AT_name        : abc


GNU Fortran (GCC) version 4.4.0 20081005 (experimental) (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.4.0 20081005 (experimental), GMP version 4.2.2, MPFR version 2.3.1.

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
 <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram)
  <2><4b>: Abbrev Number: 3 (DW_TAG_common_block)
   <3><5c>: Abbrev Number: 4 (DW_TAG_variable)
   <3><72>: Abbrev Number: 4 (DW_TAG_variable)
   <3><88>: Abbrev Number: 4 (DW_TAG_variable)
 <1><a7>: Abbrev Number: 2 (DW_TAG_subprogram)
  <2><c5>: Abbrev Number: 6 (DW_TAG_variable)
 <1><db>: Abbrev Number: 7 (DW_TAG_subprogram)

The section .debug_info contains:
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    < c>   DW_AT_producer    : (indirect string, offset: 0x1e): GNU Fortran 4.4.0 20081005 (experimental)
    <10>   DW_AT_language    : 14       (Fortran 95)
    <11>   DW_AT_name        : (indirect string, offset: 0x0): abc.f90
 <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram)
    <2f>   DW_AT_name        : a
 <2><4b>: Abbrev Number: 3 (DW_TAG_common_block)
    <4c>   DW_AT_name        : (indirect string, offset: 0x8): block
    <52>   DW_AT_location    : 9 byte block: 3 0 c 60 0 0 0 0 0         (DW_OP_addr: 600c00)
 <3><5c>: Abbrev Number: 4 (DW_TAG_variable)
    <5d>   DW_AT_name        : a_i
    <68>   DW_AT_location    : 9 byte block: 3 0 c 60 0 0 0 0 0         (DW_OP_addr: 600c00)
 <3><72>: Abbrev Number: 4 (DW_TAG_variable)
    <73>   DW_AT_name        : b_i
    <7e>   DW_AT_location    : 9 byte block: 3 0 c 60 0 0 0 0 0         (DW_OP_addr: 600c00)
 <3><88>: Abbrev Number: 4 (DW_TAG_variable)
    <89>   DW_AT_name        : a_i
    <94>   DW_AT_location    : 9 byte block: 3 0 c 60 0 0 0 0 0         (DW_OP_addr: 600c00)
 <1><a7>: Abbrev Number: 2 (DW_TAG_subprogram)
    <a9>   DW_AT_name        : b
 <2><c5>: Abbrev Number: 6 (DW_TAG_variable)
    <c6>   DW_AT_name        : a_i
    <d0>   DW_AT_location    : 2 byte block: 91 6c      (DW_OP_fbreg: -20)
 <1><db>: Abbrev Number: 7 (DW_TAG_subprogram)
    <dd>   DW_AT_name        : c
 <1><f5>: Abbrev Number: 8 (DW_TAG_subprogram)
    <f7>   DW_AT_name        : abc
    <111>   DW_AT_calling_convention: 2 (program)
Comment 1 Jan Kratochvil 2008-10-05 15:33:51 UTC
Saw there also needless DW_OP_plus_uconst - it could be single DW_OP_addr for all the common block variables (which would make the GDB support a bit easier).

program a2
  INTEGER*4 a
  INTEGER*4 b
  common /block/a,b
  a = 1
  a = 2
end program a2

 <2><4d>: Abbrev Number: 3 (DW_TAG_common_block)
    <4e>   DW_AT_name        : (indirect string, offset: 0x46): block
    <54>   DW_AT_location    : 9 byte block: 3 e0 a 60 0 0 0 0 0        (DW_OP_addr: 600ae0)
 <3><5e>: Abbrev Number: 4 (DW_TAG_variable)
    <5f>   DW_AT_name        : a
    <68>   DW_AT_location    : 9 byte block: 3 e0 a 60 0 0 0 0 0        (DW_OP_addr: 600ae0)
 <3><72>: Abbrev Number: 4 (DW_TAG_variable)
    <73>   DW_AT_name        : b
    <7c>   DW_AT_location    : 11 byte block: 3 e0 a 60 0 0 0 0 0 23 4  (DW_OP_addr: 600ae0; DW_OP_plus_uconst: 4)
Comment 2 Jakub Jelinek 2008-10-07 18:15:39 UTC
Subject: Bug 37738

Author: jakub
Date: Tue Oct  7 18:14:16 2008
New Revision: 140944

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140944
Log:
	PR debug/37738
	* dwarf2out.c (common_block_die_table): New variable.
	(common_block_die_table_hash, common_block_die_table_eq): New
	functions.
	(gen_variable_die): Look up a DW_TAG_common_block die for a particular
	COMMON block in the current scope rather than globally.  Optimize
	DW_OP_addr SYMBOL_REF DW_OP_plus_uconst off into
	DW_OP_addr SYMBOL_REF+off.

	* gfortran.dg/debug/pr37738.f: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/debug/pr37738.f
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog

Comment 3 Mikael Morin 2008-12-08 22:23:12 UTC
Is it fixed?
Comment 4 Jakub Jelinek 2008-12-08 22:42:22 UTC
Fixed.
Comment 5 Robert Mance 2009-08-18 21:01:18 UTC
(In reply to comment #4)
> Fixed.

Could you please tell me what version of gfortran this is fixed in?  I'm working the Intel Fortran compiler debug information at the moment regarding a request to add DW_AT_common_inclusion to our output.  Seems like gfortran has actually decided to move in Intel's direction here.  I'd like to see the output that gfortran is now creating, and be able to run that version of gfortran here.

Thanks.

Bob
Comment 6 Jakub Jelinek 2009-08-18 21:17:06 UTC
GCC 4.4.0/4.4.1 have it, as well as GCC trunk.
Comment 7 Robert Mance 2009-08-19 21:28:34 UTC
I've managed to download and install 4.4.5 of gfortran and can verify that what you're doing here is just about identical to what ifort is doing.  

I have a request to emit a DW_TAG_common_inclusion record in our dwarf output for Fortran named commons.  As you probably know, DW_TAG_common_inclusion would contain a DW_AT_reference entry that would refer to a single DW_TAG_common_block that would be shared by all of the common users.  

While that sounds good, it seems at best impractical, and at worse, impossible.  Users of commons are free to map them as they like.  Declaring a single common block that would satisfy all users of the common would be tricky, and perhaps impossible, if two such users both declared a variable with the same name, but with different types and locations in the common.

It gets worse when you consider multiple subroutines including the common in separately compiled programs.

The only potential use here maybe when an include statement is used to bring a named common into multiple subroutines.  We currently don't know that is happening (in debug info output), but given enough time and code, might be able to do that.

I'm just curious about views on this and if gfortran has any plans to implement support for DW_TAG_common_inclusion.

Thanks.

Bob
Comment 8 Tobias Burnus 2009-08-21 18:16:29 UTC
(In reply to comment #7)
> I have a request to emit a DW_TAG_common_inclusion record in our dwarf output
> for Fortran named commons.  [...]
> I'm just curious about views on this and if gfortran has any plans to implement
> support for DW_TAG_common_inclusion.

Currently, there no plan to implement it; simply because there was no request for it and other items seem to be more important. I create PR 41143 to track this, but I do not think that anyone will do much about it any time soon - that includes thinking about how and whether to implement it. (But I might be wrong and it might get implemented/considered sooner than I think.)