Skip to content

Commit 3fa62ef

Browse files
committed
[flang] Add semantic check for C1520
As Fortran 2018 C1520, if proc-language-binding-spec with NAME= is specified, then proc-decl-list shall contain exactly one proc-decl, which shall neither have the POINTER attribute nor be a dummy procedure. Add this check. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D127725
1 parent 4308416 commit 3fa62ef

File tree

4 files changed

+56
-4
lines changed

4 files changed

+56
-4
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,8 @@ static const std::string *DefinesBindCName(const Symbol &symbol) {
18711871
const auto *subp{symbol.detailsIf<SubprogramDetails>()};
18721872
if ((subp && !subp->isInterface() &&
18731873
ClassifyProcedure(symbol) != ProcedureDefinitionClass::Internal) ||
1874-
symbol.has<ObjectEntityDetails>() || symbol.has<CommonBlockDetails>()) {
1874+
symbol.has<ObjectEntityDetails>() || symbol.has<CommonBlockDetails>() ||
1875+
symbol.has<ProcEntityDetails>()) {
18751876
// Symbol defines data or entry point
18761877
return symbol.GetBindName();
18771878
} else {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
10471047
// Set when walking DATA & array constructor implied DO loop bounds
10481048
// to warn about use of the implied DO intex therein.
10491049
std::optional<SourceName> checkIndexUseInOwnBounds_;
1050+
bool hasBindCName_{false};
10501051

10511052
bool HandleAttributeStmt(Attr, const std::list<parser::Name> &);
10521053
Symbol &HandleAttributeStmt(Attr, const parser::Name &);
@@ -4679,12 +4680,22 @@ void DeclarationVisitor::Post(const parser::FillDecl &x) {
46794680
}
46804681
ClearArraySpec();
46814682
}
4682-
bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt &) {
4683+
bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt &x) {
46834684
CHECK(!interfaceName_);
4685+
const auto &procAttrSpec{std::get<std::list<parser::ProcAttrSpec>>(x.t)};
4686+
for (const parser::ProcAttrSpec &procAttr : procAttrSpec) {
4687+
if (auto *bindC{std::get_if<parser::LanguageBindingSpec>(&procAttr.u)}) {
4688+
if (bindC->v.has_value()) {
4689+
hasBindCName_ = true;
4690+
break;
4691+
}
4692+
}
4693+
}
46844694
return BeginDecl();
46854695
}
46864696
void DeclarationVisitor::Post(const parser::ProcedureDeclarationStmt &) {
46874697
interfaceName_ = nullptr;
4698+
hasBindCName_ = false;
46884699
EndDecl();
46894700
}
46904701
bool DeclarationVisitor::Pre(const parser::DataComponentDefStmt &x) {
@@ -4752,6 +4763,10 @@ void DeclarationVisitor::Post(const parser::ProcDecl &x) {
47524763
if (dtDetails) {
47534764
dtDetails->add_component(symbol);
47544765
}
4766+
if (hasBindCName_ && (IsPointer(symbol) || IsDummy(symbol))) {
4767+
Say(symbol.name(),
4768+
"BIND(C) procedure with NAME= specified can neither have POINTER attribute nor be a dummy procedure"_err_en_US);
4769+
}
47554770
}
47564771

47574772
bool DeclarationVisitor::Pre(const parser::TypeBoundProcedurePart &) {

flang/test/Semantics/bind-c04.f90

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1
2+
! Check for C1520
3+
! If proc-language-binding-spec (bind(c)) with NAME= is specified, then
4+
! proc-decl-list shall contain exactly one proc-decl, which shall neither have
5+
! the POINTER attribute nor be a dummy procedure.
6+
7+
subroutine sub(x, y)
8+
9+
interface
10+
subroutine proc() bind(c)
11+
end
12+
end interface
13+
14+
!ERROR: Two symbols have the same BIND(C) name 'aaa'
15+
procedure(proc), bind(c, name="aaa") :: pc1, pc2
16+
17+
!ERROR: BIND(C) procedure with NAME= specified can neither have POINTER attribute nor be a dummy procedure
18+
procedure(proc), bind(c, name="bbb"), pointer :: pc3
19+
20+
!ERROR: BIND(C) procedure with NAME= specified can neither have POINTER attribute nor be a dummy procedure
21+
procedure(proc), bind(c, name="ccc") :: x
22+
23+
procedure(proc), bind(c) :: pc4, pc5
24+
25+
!ERROR: BIND(C) procedure with NAME= specified can neither have POINTER attribute nor be a dummy procedure
26+
procedure(proc), bind(c, name="pc6"), pointer :: pc6
27+
28+
procedure(proc), bind(c), pointer :: pc7
29+
30+
procedure(proc), bind(c) :: y
31+
32+
!WARNING: Attribute 'BIND(C)' cannot be used more than once
33+
!ERROR: BIND(C) procedure with NAME= specified can neither have POINTER attribute nor be a dummy procedure
34+
procedure(proc), bind(c, name="pc8"), bind(c), pointer :: pc8
35+
36+
end

flang/test/Semantics/modfile16.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module m
33
character(2), parameter :: prefix = 'c_'
44
integer, bind(c, name='c_a') :: a
5-
procedure(sub), bind(c, name=prefix//'b'), pointer :: b
5+
procedure(sub), bind(c, name=prefix//'b') :: b
66
type, bind(c) :: t
77
real :: c
88
end type
@@ -15,7 +15,7 @@ subroutine sub() bind(c, name='sub')
1515
!module m
1616
! character(2_4,1),parameter::prefix="c_"
1717
! integer(4),bind(c, name="c_a")::a
18-
! procedure(sub),bind(c, name="c_b"),pointer::b
18+
! procedure(sub),bind(c, name="c_b")::b
1919
! type,bind(c)::t
2020
! real(4)::c
2121
! end type

0 commit comments

Comments
 (0)