Bug 59015 - I/O of PARAMETER derived type with private component is forbidden
Summary: I/O of PARAMETER derived type with private component is forbidden
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, diagnostic
Depends on:
Blocks: 58020
  Show dependency treegraph
 
Reported: 2013-11-05 21:37 UTC by Francois-Xavier Coudert
Modified: 2016-09-17 02:26 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-11-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2013-11-05 21:37:15 UTC
We should diagnose and prevent I/O of a derived-type object with one or more private components. Example:

module foo
  type, public :: t
    private
    integer :: hidden
  end type t

  type(t), parameter, public :: v = t(42)
end module foo
 
program test
  use foo
  print *, v
end

This currently compiles and print 42. It should be rejected.
Comment 1 Tobias Burnus 2013-11-06 08:04:28 UTC
Confirmed. Not even -pedantic -std=f95 has any effect.

Note: The issue only affects PARAMETER. For module variables, one gets:
  Error: Data transfer element at (1) cannot have PRIVATE components


Fortran 2008, "9.6.3 Data transfer input/output list", second bullet point of paragraph 7 [see last sentence after the ";"]

"If a list item of derived type in an unformatted input/output statement is not processed by a defined input/output procedure (9.6.4.8), and if any subobject of that list item would be processed by a defined input/output procedure, the list item is treated as if all of the components of the object were specified in the list in component order (4.5.4.7); those components shall be accessible in the scoping unit containing the input/output statement and shall not be pointers or allocatable."
Comment 2 Francois-Xavier Coudert 2013-11-06 09:42:57 UTC
We don't trigger the check in resolve.c:resolve_transfer() because we bail out early:

  if (exp == NULL || (exp->expr_type != EXPR_VARIABLE
                      && exp->expr_type != EXPR_FUNCTION))
    return;

I'm testing a patch to allow EXPR_STRUCTURE to go through the checks.
Comment 3 Francois-Xavier Coudert 2013-11-06 10:07:55 UTC
Allowing EXPR_STRUCTURE to go through the tests (by adding it along EXPR_VARIABLE and EXPR_FUNCTION) leads to a failure of c_ptr_tests_16.f90 (the rest of the testsuite works ok). The code that triggers it uses a TRANSFER:

module foo
  type mytype
    integer, private :: a, b, c
  end type mytype
end module foo

  use foo
  type(mytype) x
  print *, transfer(32512, x)
end

There is a segfault when it tries to access the symbol of the TRANSFER:

  sym = exp->symtree->n.sym;

I'm not able to dig any further, so I'll let someone else take care of it.
Comment 4 Jerry DeLisle 2016-09-17 02:26:42 UTC
This is now fixed on trunk with DTIO implentation. See PR48298.