This is an archive of the discontinued LLVM Phabricator instance.

[flang] Support known constant lengths in DynamicType
ClosedPublic

Authored by klausler on Jun 2 2021, 5:19 PM.

Details

Summary

The constexpr-capable class evaluate::DynamicType represented
CHARACTER length only with a nullable pointer into the declared
parameters of types in the symbol table, which works fine for
anything with a declaration but turns out to not suffice to
describe the results of the ACHAR() and CHAR() intrinsic
functions. So extend DynamicType to also accommodate known
constant CHARACTER lengths, too; use them for ACHAR & CHAR;
clean up several use sites and fix regressions found in test.

Diff Detail

Event Timeline

klausler created this revision.Jun 2 2021, 5:19 PM
klausler requested review of this revision.Jun 2 2021, 5:19 PM
PeteSteinfeld accepted this revision.Jun 2 2021, 7:50 PM
PeteSteinfeld added a subscriber: PeteSteinfeld.

All builds, tests, and looks good.

This revision is now accepted and ready to land.Jun 2 2021, 7:50 PM
jeanPerier accepted this revision.Jun 3 2021, 6:01 AM

Looks good to me

This revision was landed with ongoing or failed builds.Jun 3 2021, 2:25 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2021, 2:25 PM

FYI, this change broke compiling flang with GCC 7 on Ubuntu 18.04, with build errors like these:

In file included from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/call.h:12:0,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/intrinsics.h:12,
                 from /home/ubuntu/code/llvm-project/flang/lib/Evaluate/intrinsics.cpp:9:
/home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/common.h:187:16: error: explicitly defaulted function ‘constexpr Fortran::evaluate::DynamicType& Fortran::evaluate::DynamicType::operator=(const Fortran::evaluate::DynamicType&)’ cannot be declared as constexpr because the implicit declaration is not constexpr:
   constexpr t &operator=(const t &) = default; \
                ^
/home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/type.h:103:3: note: in expansion of macro ‘CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS’
   CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS(DynamicType)
   ^
In file included from /usr/include/c++/7/bits/node_handle.h:39:0,
                 from /usr/include/c++/7/bits/hashtable.h:37,
                 from /usr/include/c++/7/unordered_map:47,
                 from /usr/include/c++/7/functional:60,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Common/idioms.h:27,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Common/Fortran.h:15,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/common.h:12,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/call.h:12,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/intrinsics.h:12,
                 from /home/ubuntu/code/llvm-project/flang/lib/Evaluate/intrinsics.cpp:9:
/usr/include/c++/7/optional:453:11: note: defaulted constructor calls non-constexpr ‘std::optional<long int>& std::optional<long int>::operator=(const std::optional<long int>&)’
     class optional
           ^~~~~~~~
/usr/include/c++/7/optional:453:11: note: ‘std::optional<long int>& std::optional<long int>::operator=(const std::optional<long int>&)’ is not usable as a constexpr function because:
/usr/include/c++/7/optional:351:7: note: defaulted constructor calls non-constexpr ‘std::_Optional_base<_Tp>& std::_Optional_base<_Tp>::operator=(const std::_Optional_base<_Tp>&) [with _Tp = long int]’
       operator=(const _Optional_base& __other)
       ^~~~~~~~

FYI, this change broke compiling flang with GCC 7 on Ubuntu 18.04, with build errors like these:

In file included from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/call.h:12:0,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/intrinsics.h:12,
                 from /home/ubuntu/code/llvm-project/flang/lib/Evaluate/intrinsics.cpp:9:
/home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/common.h:187:16: error: explicitly defaulted function ‘constexpr Fortran::evaluate::DynamicType& Fortran::evaluate::DynamicType::operator=(const Fortran::evaluate::DynamicType&)’ cannot be declared as constexpr because the implicit declaration is not constexpr:
   constexpr t &operator=(const t &) = default; \
                ^
/home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/type.h:103:3: note: in expansion of macro ‘CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS’
   CONSTEXPR_CONSTRUCTORS_AND_ASSIGNMENTS(DynamicType)
   ^
In file included from /usr/include/c++/7/bits/node_handle.h:39:0,
                 from /usr/include/c++/7/bits/hashtable.h:37,
                 from /usr/include/c++/7/unordered_map:47,
                 from /usr/include/c++/7/functional:60,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Common/idioms.h:27,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Common/Fortran.h:15,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/common.h:12,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/call.h:12,
                 from /home/ubuntu/code/llvm-project/flang/include/flang/Evaluate/intrinsics.h:12,
                 from /home/ubuntu/code/llvm-project/flang/lib/Evaluate/intrinsics.cpp:9:
/usr/include/c++/7/optional:453:11: note: defaulted constructor calls non-constexpr ‘std::optional<long int>& std::optional<long int>::operator=(const std::optional<long int>&)’
     class optional
           ^~~~~~~~
/usr/include/c++/7/optional:453:11: note: ‘std::optional<long int>& std::optional<long int>::operator=(const std::optional<long int>&)’ is not usable as a constexpr function because:
/usr/include/c++/7/optional:351:7: note: defaulted constructor calls non-constexpr ‘std::_Optional_base<_Tp>& std::_Optional_base<_Tp>::operator=(const std::_Optional_base<_Tp>&) [with _Tp = long int]’
       operator=(const _Optional_base& __other)
       ^~~~~~~~

I have seen similar failure with GCC 7.4

I'll see whether there's a patch that can work around those old compilers. Thanks for the notification.