Skip to content

Commit 45cd405

Browse files
committed
[flang] Add clang-tidy check for braces around if
Flang diverges from the llvm coding style in that it requires braces around the bodies of if/while/etc statements, even when the body is a single statement. This commit adds the readability-braces-around-statements check to flang's clang-tidy config file. Hopefully the premerge bots will pick it up and report violations in Phabricator. We also explicitly disable the check in the directories corresponding to the Lower and Optimizer libraries, which rely heavily on mlir and llvm and therefore follow their coding style. Likewise for the tools directory. We also fix any outstanding violations in the runtime and in lib/Semantics. Differential Revision: https://reviews.llvm.org/D104100
1 parent 29843cb commit 45cd405

File tree

13 files changed

+64
-32
lines changed

13 files changed

+64
-32
lines changed

flang/.clang-tidy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Checks: '-llvm-include-order,-readability-identifier-naming,-clang-diagnostic-*'
1+
Checks: '-llvm-include-order,readability-braces-around-statements,-readability-identifier-naming,-clang-diagnostic-*'
22
InheritParentConfig: true

flang/docs/C++style.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,10 @@ Don't try to make columns of variable names or comments
115115
align vertically -- they are maintenance problems.
116116

117117
Always wrap the bodies of `if()`, `else`, `while()`, `for()`, `do`, &c.
118-
with braces, even when the body is a single statement or empty. The
118+
with braces, even when the body is a single statement or empty. Note that this
119+
diverges from the LLVM coding style. In parts of the codebase that make heavy
120+
use of LLVM or MLIR APIs (e.g. the Lower and Optimizer libraries), use the
121+
LLVM style instead. The
119122
opening `{` goes on
120123
the end of the line, not on the next line. Functions also put the opening
121124
`{` after the formal arguments or new-style result type, not on the next

flang/include/flang/Lower/.clang-tidy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Checks: 'readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
1+
Checks: '-readability-braces-around-statements,readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
22
InheritParentConfig: true
33
CheckOptions:
44
- key: readability-identifier-naming.MemberCase

flang/include/flang/Optimizer/.clang-tidy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Checks: 'readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
1+
Checks: '-readability-braces-around-statements,readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
22
InheritParentConfig: true
33
CheckOptions:
44
- key: readability-identifier-naming.MemberCase

flang/lib/Lower/.clang-tidy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Checks: 'readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
1+
Checks: '-readability-braces-around-statements,readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
22
InheritParentConfig: true
33
CheckOptions:
44
- key: readability-identifier-naming.MemberCase

flang/lib/Optimizer/.clang-tidy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Checks: 'readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
1+
Checks: '-readability-braces-around-statements,readability-identifier-naming,llvm-include-order,clang-diagnostic-*'
22
InheritParentConfig: true
33
CheckOptions:
44
- key: readability-identifier-naming.MemberCase

flang/lib/Semantics/canonicalize-acc.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ class CanonicalizationOfAcc {
6464
std::size_t tileArgNb = listTileExpr.size();
6565

6666
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
67-
if (outer->IsDoConcurrent())
67+
if (outer->IsDoConcurrent()) {
6868
return; // Tile is not allowed on DO CONURRENT
69+
}
6970
for (const parser::DoConstruct *loop{&*outer}; loop && tileArgNb > 0;
7071
--tileArgNb) {
7172
const auto &block{std::get<parser::Block>(loop->t)};
@@ -90,8 +91,9 @@ class CanonicalizationOfAcc {
9091
template <typename C, typename D>
9192
void CheckDoConcurrentClauseRestriction(const C &x) {
9293
const auto &doCons{std::get<std::optional<parser::DoConstruct>>(x.t)};
93-
if (!doCons->IsDoConcurrent())
94+
if (!doCons->IsDoConcurrent()) {
9495
return;
96+
}
9597
const auto &beginLoopDirective = std::get<D>(x.t);
9698
const auto &accClauseList =
9799
std::get<parser::AccClauseList>(beginLoopDirective.t);

flang/lib/Semantics/check-acc-structure.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,25 @@ bool AccStructureChecker::IsComputeConstruct(
6565
}
6666

6767
bool AccStructureChecker::IsInsideComputeConstruct() const {
68-
if (dirContext_.size() <= 1)
68+
if (dirContext_.size() <= 1) {
6969
return false;
70+
}
7071

7172
// Check all nested context skipping the first one.
7273
for (std::size_t i = dirContext_.size() - 1; i > 0; --i) {
73-
if (IsComputeConstruct(dirContext_[i - 1].directive))
74+
if (IsComputeConstruct(dirContext_[i - 1].directive)) {
7475
return true;
76+
}
7577
}
7678
return false;
7779
}
7880

7981
void AccStructureChecker::CheckNotInComputeConstruct() {
80-
if (IsInsideComputeConstruct())
82+
if (IsInsideComputeConstruct()) {
8183
context_.Say(GetContext().directiveSource,
8284
"Directive %s may not be called within a compute region"_err_en_US,
8385
ContextDirectiveAsFortran());
86+
}
8487
}
8588

8689
void AccStructureChecker::Enter(const parser::AccClause &x) {
@@ -148,14 +151,15 @@ void AccStructureChecker::Leave(
148151
if (cl != llvm::acc::Clause::ACCC_create &&
149152
cl != llvm::acc::Clause::ACCC_copyin &&
150153
cl != llvm::acc::Clause::ACCC_device_resident &&
151-
cl != llvm::acc::Clause::ACCC_link)
154+
cl != llvm::acc::Clause::ACCC_link) {
152155
context_.Say(GetContext().directiveSource,
153156
"%s clause is not allowed on the %s directive in module "
154157
"declaration "
155158
"section"_err_en_US,
156159
parser::ToUpperCaseLetters(
157160
llvm::acc::getOpenACCClauseName(cl).str()),
158161
ContextDirectiveAsFortran());
162+
}
159163
}
160164
}
161165
dirContext_.pop_back();
@@ -368,8 +372,9 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyin &c) {
368372
const auto &modifierClause{c.v};
369373
if (const auto &modifier{
370374
std::get<std::optional<parser::AccDataModifier>>(modifierClause.t)}) {
371-
if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyin))
375+
if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyin)) {
372376
return;
377+
}
373378
if (modifier->v != parser::AccDataModifier::Modifier::ReadOnly) {
374379
context_.Say(GetContext().clauseSource,
375380
"Only the READONLY modifier is allowed for the %s clause "
@@ -387,8 +392,9 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) {
387392
const auto &modifierClause{c.v};
388393
if (const auto &modifier{
389394
std::get<std::optional<parser::AccDataModifier>>(modifierClause.t)}) {
390-
if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyout))
395+
if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyout)) {
391396
return;
397+
}
392398
if (modifier->v != parser::AccDataModifier::Modifier::Zero) {
393399
context_.Say(GetContext().clauseSource,
394400
"Only the ZERO modifier is allowed for the %s clause "

flang/lib/Semantics/check-omp-structure.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,9 @@ void OmpStructureChecker::CheckDistLinear(
545545
// Get collapse level, if given, to find which loops are "associated."
546546
std::int64_t collapseVal{GetOrdCollapseLevel(x)};
547547
// Include the top loop if no collapse is specified
548-
if (collapseVal == 0)
548+
if (collapseVal == 0) {
549549
collapseVal = 1;
550+
}
550551

551552
// Match the loop index variables with the collected symbols from linear
552553
// clauses.
@@ -560,8 +561,9 @@ void OmpStructureChecker::CheckDistLinear(
560561
indexVars.erase(*(itrVal.symbol));
561562
}
562563
collapseVal--;
563-
if (collapseVal == 0)
564+
if (collapseVal == 0) {
564565
break;
566+
}
565567
}
566568
// Get the next DoConstruct if block is not empty.
567569
const auto &block{std::get<parser::Block>(loop->t)};
@@ -782,8 +784,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
782784
const auto &dir{std::get<parser::Verbatim>(x.t)};
783785
const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
784786
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
785-
if (objectList)
787+
if (objectList) {
786788
CheckIsVarPartOfAnotherVar(dir.source, *objectList);
789+
}
787790
}
788791

789792
void OmpStructureChecker::Leave(const parser::OpenMPExecutableAllocate &x) {

flang/lib/Semantics/resolve-directives.cpp

+25-13
Original file line numberDiff line numberDiff line change
@@ -694,20 +694,22 @@ Symbol *AccAttributeVisitor::ResolveName(const parser::Name &name) {
694694
bool AccAttributeVisitor::Pre(const parser::OpenACCRoutineConstruct &x) {
695695
const auto &optName{std::get<std::optional<parser::Name>>(x.t)};
696696
if (optName) {
697-
if (!ResolveName(*optName))
697+
if (!ResolveName(*optName)) {
698698
context_.Say((*optName).source,
699699
"No function or subroutine declared for '%s'"_err_en_US,
700700
(*optName).source);
701+
}
701702
}
702703
return true;
703704
}
704705

705706
bool AccAttributeVisitor::Pre(const parser::AccBindClause &x) {
706707
if (const auto *name{std::get_if<parser::Name>(&x.u)}) {
707-
if (!ResolveName(*name))
708+
if (!ResolveName(*name)) {
708709
context_.Say(name->source,
709710
"No function or subroutine declared for '%s'"_err_en_US,
710711
name->source);
712+
}
711713
}
712714
return true;
713715
}
@@ -750,13 +752,14 @@ void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
750752
std::visit(
751753
common::visitors{
752754
[&](const parser::Designator &designator) {
753-
if (!IsLastNameArray(designator))
755+
if (!IsLastNameArray(designator)) {
754756
context_.Say(designator.source,
755757
"Only array element or subarray are allowed in %s directive"_err_en_US,
756758
parser::ToUpperCaseLetters(
757759
llvm::acc::getOpenACCDirectiveName(
758760
GetContext().directive)
759761
.str()));
762+
}
760763
},
761764
[&](const auto &name) {
762765
context_.Say(name.source,
@@ -777,14 +780,15 @@ void AccAttributeVisitor::DoNotAllowAssumedSizedArray(
777780
common::visitors{
778781
[&](const parser::Designator &designator) {
779782
const auto &name{GetLastName(designator)};
780-
if (name.symbol && semantics::IsAssumedSizeArray(*name.symbol))
783+
if (name.symbol && semantics::IsAssumedSizeArray(*name.symbol)) {
781784
context_.Say(designator.source,
782785
"Assumed-size dummy arrays may not appear on the %s "
783786
"directive"_err_en_US,
784787
parser::ToUpperCaseLetters(
785788
llvm::acc::getOpenACCDirectiveName(
786789
GetContext().directive)
787790
.str()));
791+
}
788792
},
789793
[&](const auto &name) {
790794

@@ -861,13 +865,14 @@ void AccAttributeVisitor::EnsureAllocatableOrPointer(
861865
common::visitors{
862866
[&](const parser::Designator &designator) {
863867
const auto &lastName{GetLastName(designator)};
864-
if (!IsAllocatableOrPointer(*lastName.symbol))
868+
if (!IsAllocatableOrPointer(*lastName.symbol)) {
865869
context_.Say(designator.source,
866870
"Argument `%s` on the %s clause must be a variable or "
867871
"array with the POINTER or ALLOCATABLE attribute"_err_en_US,
868872
lastName.symbol->name(),
869873
parser::ToUpperCaseLetters(
870874
llvm::acc::getOpenACCClauseName(clause).str()));
875+
}
871876
},
872877
[&](const auto &name) {
873878
context_.Say(name.source,
@@ -1349,8 +1354,9 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclarativeAllocate &x) {
13491354
bool OmpAttributeVisitor::Pre(const parser::OpenMPExecutableAllocate &x) {
13501355
PushContext(x.source, llvm::omp::Directive::OMPD_allocate);
13511356
const auto &list{std::get<std::optional<parser::OmpObjectList>>(x.t)};
1352-
if (list)
1357+
if (list) {
13531358
ResolveOmpObjectList(*list, Symbol::Flag::OmpExecutableAllocateDirective);
1359+
}
13541360
return true;
13551361
}
13561362

@@ -1376,8 +1382,9 @@ void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) {
13761382
bool OmpAttributeVisitor::IsNestedInDirective(llvm::omp::Directive directive) {
13771383
if (dirContext_.size() >= 1) {
13781384
for (std::size_t i = dirContext_.size() - 1; i > 0; --i) {
1379-
if (dirContext_[i - 1].directive == directive)
1385+
if (dirContext_[i - 1].directive == directive) {
13801386
return true;
1387+
}
13811388
}
13821389
}
13831390
return false;
@@ -1389,17 +1396,19 @@ void OmpAttributeVisitor::Post(const parser::OpenMPExecutableAllocate &x) {
13891396
// parser::Unwrap instead of the following loop
13901397
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
13911398
for (const auto &clause : clauseList.v) {
1392-
if (std::get_if<parser::OmpClause::Allocator>(&clause.u))
1399+
if (std::get_if<parser::OmpClause::Allocator>(&clause.u)) {
13931400
hasAllocator = true;
1401+
}
13941402
}
13951403

1396-
if (IsNestedInDirective(llvm::omp::Directive::OMPD_target) && !hasAllocator)
1404+
if (IsNestedInDirective(llvm::omp::Directive::OMPD_target) && !hasAllocator) {
13971405
// TODO: expand this check to exclude the case when a requires
13981406
// directive with the dynamic_allocators clause is present
13991407
// in the same compilation unit (OMP5.0 2.11.3).
14001408
context_.Say(x.source,
14011409
"ALLOCATE directives that appear in a TARGET region "
14021410
"must specify an allocator clause"_err_en_US);
1411+
}
14031412
PopContext();
14041413
}
14051414

@@ -1675,16 +1684,18 @@ void ResolveOmpParts(
16751684
void OmpAttributeVisitor::CheckDataCopyingClause(
16761685
const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
16771686
const auto *checkSymbol{&symbol};
1678-
if (const auto *details{symbol.detailsIf<HostAssocDetails>()})
1687+
if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
16791688
checkSymbol = &details->symbol();
1689+
}
16801690

16811691
if (ompFlag == Symbol::Flag::OmpCopyIn) {
16821692
// List of items/objects that can appear in a 'copyin' clause must be
16831693
// 'threadprivate'
1684-
if (!checkSymbol->test(Symbol::Flag::OmpThreadprivate))
1694+
if (!checkSymbol->test(Symbol::Flag::OmpThreadprivate)) {
16851695
context_.Say(name.source,
16861696
"Non-THREADPRIVATE object '%s' in COPYIN clause"_err_en_US,
16871697
checkSymbol->name());
1698+
}
16881699
} else if (ompFlag == Symbol::Flag::OmpCopyPrivate &&
16891700
GetContext().directive == llvm::omp::Directive::OMPD_single) {
16901701
// A list item that appears in a 'copyprivate' clause may not appear on a
@@ -1715,10 +1726,11 @@ void OmpAttributeVisitor::CheckPrivateDSAObject(
17151726
const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
17161727
const auto &ultimateSymbol{symbol.GetUltimate()};
17171728
llvm::StringRef clauseName{"PRIVATE"};
1718-
if (ompFlag == Symbol::Flag::OmpFirstPrivate)
1729+
if (ompFlag == Symbol::Flag::OmpFirstPrivate) {
17191730
clauseName = "FIRSTPRIVATE";
1720-
else if (ompFlag == Symbol::Flag::OmpLastPrivate)
1731+
} else if (ompFlag == Symbol::Flag::OmpLastPrivate) {
17211732
clauseName = "LASTPRIVATE";
1733+
}
17221734

17231735
if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
17241736
context_.Say(name.source,

flang/runtime/ISO_Fortran_binding.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,9 @@ int CFI_establish(CFI_cdesc_t *descriptor, void *base_addr,
236236
}
237237
if (type == CFI_type_struct || type == CFI_type_other ||
238238
IsCharacterType(type)) {
239-
if (elem_len <= 0)
239+
if (elem_len <= 0) {
240240
return CFI_INVALID_ELEM_LEN;
241+
}
241242
} else {
242243
elem_len = MinElemLen(type);
243244
assert(elem_len > 0 && "Unknown element length for type");

flang/tools/.clang-tidy

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Checks: '-readability-braces-around-statements'
2+
InheritParentConfig: true

flang/unittests/RuntimeGTest/CrashHandlerFixture.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
// Register the crash handler above when creating each unit test in this suite
2929
void CrashHandlerFixture::SetUp() {
3030
static bool isCrashHanlderRegistered{false};
31-
if (!isCrashHanlderRegistered)
31+
32+
if (!isCrashHanlderRegistered) {
3233
Fortran::runtime::Terminator::RegisterCrashHandler(CatchCrash);
34+
}
35+
3336
isCrashHanlderRegistered = true;
3437
}

0 commit comments

Comments
 (0)