Skip to content

Commit c37da68

Browse files
committed
[Flang] Fix SIMPLE attribute logic and formatting per review
- Removed `|| proc.IsSimple()` from the `if (proc.IsPure())` condition in check-expression.cpp. - Removed `Attr::Simple` from the isPureProcedureImpl helper in tools.cpp. - Fixed formatting issues.
1 parent f94e36d commit c37da68

File tree

14 files changed

+148
-1723
lines changed

14 files changed

+148
-1723
lines changed

flang/include/flang/Evaluate/call.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class ActualArgument {
9999
}
100100

101101
const Symbol *GetAssumedTypeDummy() const {
102-
if (const AssumedType * aType{std::get_if<AssumedType>(&u_)}) {
102+
if (const AssumedType *aType{std::get_if<AssumedType>(&u_)}) {
103103
return &aType->symbol();
104104
} else {
105105
return nullptr;
@@ -219,6 +219,7 @@ struct ProcedureDesignator {
219219
int Rank() const;
220220
bool IsElemental() const;
221221
bool IsPure() const;
222+
bool IsSimple() const;
222223
std::optional<Expr<SubscriptInteger>> LEN() const;
223224
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
224225

flang/include/flang/Evaluate/characteristics.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,10 @@ struct FunctionResult {
363363

364364
// 15.3.1
365365
struct Procedure {
366-
ENUM_CLASS(Attr, Pure, Elemental, BindC, ImplicitInterface, NullPointer,
367-
NullAllocatable, Subroutine)
366+
ENUM_CLASS(Attr, Pure, Simple, Elemental, BindC, ImplicitInterface,
367+
NullPointer, NullAllocatable, Subroutine)
368368
using Attrs = common::EnumSet<Attr, Attr_enumSize>;
369-
Procedure(){};
369+
Procedure() {};
370370
Procedure(FunctionResult &&, DummyArguments &&, Attrs);
371371
Procedure(DummyArguments &&, Attrs); // for subroutines and NULL()
372372
DECLARE_CONSTRUCTORS_AND_ASSIGNMENTS(Procedure)
@@ -396,6 +396,7 @@ struct Procedure {
396396
bool IsSubroutine() const { return attrs.test(Attr::Subroutine); }
397397

398398
bool IsPure() const { return attrs.test(Attr::Pure); }
399+
bool IsSimple() const { return attrs.test(Attr::Simple); }
399400
bool IsElemental() const { return attrs.test(Attr::Elemental); }
400401
bool IsBindC() const { return attrs.test(Attr::BindC); }
401402
bool HasExplicitInterface() const {

flang/include/flang/Evaluate/tools.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ const Symbol *IsArrayElement(const Expr<T> &expr, bool intoSubstring = true,
380380
bool skipComponents = false) {
381381
if (auto dataRef{ExtractDataRef(expr, intoSubstring)}) {
382382
for (const DataRef *ref{&*dataRef}; ref;) {
383-
if (const Component * component{std::get_if<Component>(&ref->u)}) {
383+
if (const Component *component{std::get_if<Component>(&ref->u)}) {
384384
ref = skipComponents ? &component->base() : nullptr;
385385
} else if (const auto *coarrayRef{std::get_if<CoarrayRef>(&ref->u)}) {
386386
ref = &coarrayRef->base();
@@ -436,7 +436,7 @@ struct ExtractCoindexedObjectHelper {
436436
return common::visit(*this, dataRef.u);
437437
}
438438
std::optional<CoarrayRef> operator()(const NamedEntity &named) const {
439-
if (const Component * component{named.UnwrapComponent()}) {
439+
if (const Component *component{named.UnwrapComponent()}) {
440440
return (*this)(*component);
441441
} else {
442442
return std::nullopt;
@@ -969,7 +969,7 @@ template <typename A> const Symbol *GetLastSymbol(const A &x) {
969969
// its set of attributes, otherwise the empty set. Also works on variables that
970970
// are pointer results of functions.
971971
template <typename A> semantics::Attrs GetAttrs(const A &x) {
972-
if (const Symbol * symbol{GetLastSymbol(x)}) {
972+
if (const Symbol *symbol{GetLastSymbol(x)}) {
973973
return symbol->attrs();
974974
} else {
975975
return {};
@@ -980,7 +980,7 @@ template <>
980980
inline semantics::Attrs GetAttrs<Expr<SomeType>>(const Expr<SomeType> &x) {
981981
if (IsVariable(x)) {
982982
if (const auto *procRef{UnwrapProcedureRef(x)}) {
983-
if (const Symbol * interface{procRef->proc().GetInterfaceSymbol()}) {
983+
if (const Symbol *interface{procRef->proc().GetInterfaceSymbol()}) {
984984
if (const auto *details{
985985
interface->detailsIf<semantics::SubprogramDetails>()}) {
986986
if (details->isFunction() &&
@@ -992,7 +992,7 @@ inline semantics::Attrs GetAttrs<Expr<SomeType>>(const Expr<SomeType> &x) {
992992
}
993993
}
994994
}
995-
if (const Symbol * symbol{GetLastSymbol(x)}) {
995+
if (const Symbol *symbol{GetLastSymbol(x)}) {
996996
return symbol->attrs();
997997
} else {
998998
return {};
@@ -1543,6 +1543,8 @@ inline bool IsAlternateEntry(const Symbol *symbol) {
15431543
bool IsVariableName(const Symbol &);
15441544
bool IsPureProcedure(const Symbol &);
15451545
bool IsPureProcedure(const Scope &);
1546+
bool IsSimpleProcedure(const Symbol &);
1547+
bool IsSimpleProcedure(const Scope &);
15461548
bool IsExplicitlyImpureProcedure(const Symbol &);
15471549
bool IsElementalProcedure(const Symbol &);
15481550
bool IsFunction(const Symbol &);

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ class ParseTreeDumper {
769769
NODE(PrefixSpec, Non_Recursive)
770770
NODE(PrefixSpec, Pure)
771771
NODE(PrefixSpec, Recursive)
772+
NODE(PrefixSpec, Simple)
772773
NODE(PrefixSpec, Attributes)
773774
NODE(PrefixSpec, Launch_Bounds)
774775
NODE(PrefixSpec, Cluster_Dims)

flang/include/flang/Parser/parse-tree.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3110,7 +3110,7 @@ struct ProcedureDeclarationStmt {
31103110

31113111
// R1527 prefix-spec ->
31123112
// declaration-type-spec | ELEMENTAL | IMPURE | MODULE |
3113-
// NON_RECURSIVE | PURE | RECURSIVE |
3113+
// NON_RECURSIVE | PURE | SIMPLE | RECURSIVE |
31143114
// (CUDA) ATTRIBUTES ( (DEVICE | GLOBAL | GRID_GLOBAL | HOST)... )
31153115
// LAUNCH_BOUNDS(expr-list) | CLUSTER_DIMS(expr-list)
31163116
struct PrefixSpec {
@@ -3121,11 +3121,12 @@ struct PrefixSpec {
31213121
EMPTY_CLASS(Non_Recursive);
31223122
EMPTY_CLASS(Pure);
31233123
EMPTY_CLASS(Recursive);
3124+
EMPTY_CLASS(Simple);
31243125
WRAPPER_CLASS(Attributes, std::list<common::CUDASubprogramAttrs>);
31253126
WRAPPER_CLASS(Launch_Bounds, std::list<ScalarIntConstantExpr>);
31263127
WRAPPER_CLASS(Cluster_Dims, std::list<ScalarIntConstantExpr>);
31273128
std::variant<DeclarationTypeSpec, Elemental, Impure, Module, Non_Recursive,
3128-
Pure, Recursive, Attributes, Launch_Bounds, Cluster_Dims>
3129+
Pure, Recursive, Simple, Attributes, Launch_Bounds, Cluster_Dims>
31293130
u;
31303131
};
31313132

flang/include/flang/Semantics/attr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ENUM_CLASS(Attr, ABSTRACT, ALLOCATABLE, ASYNCHRONOUS, BIND_C, CONTIGUOUS,
2525
DEFERRED, ELEMENTAL, EXTENDS, EXTERNAL, IMPURE, INTENT_IN, INTENT_INOUT,
2626
INTENT_OUT, INTRINSIC, MODULE, NON_OVERRIDABLE, NON_RECURSIVE, NOPASS,
2727
OPTIONAL, PARAMETER, PASS, POINTER, PRIVATE, PROTECTED, PUBLIC, PURE,
28-
RECURSIVE, SAVE, TARGET, VALUE, VOLATILE)
28+
RECURSIVE, SAVE, SIMPLE, TARGET, VALUE, VOLATILE)
2929

3030
// Set of attributes
3131
class Attrs : public common::EnumSet<Attr, Attr_enumSize> {

flang/lib/Evaluate/call.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ void ActualArgument::Parenthesize() {
6666

6767
SpecificIntrinsic::SpecificIntrinsic(
6868
IntrinsicProcedure n, characteristics::Procedure &&chars)
69-
: name{n}, characteristics{
70-
new characteristics::Procedure{std::move(chars)}} {}
69+
: name{n},
70+
characteristics{new characteristics::Procedure{std::move(chars)}} {}
7171

7272
DEFINE_DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(SpecificIntrinsic)
7373

@@ -98,7 +98,7 @@ std::optional<DynamicType> ProcedureDesignator::GetType() const {
9898
}
9999

100100
int ProcedureDesignator::Rank() const {
101-
if (const Symbol * symbol{GetSymbol()}) {
101+
if (const Symbol *symbol{GetSymbol()}) {
102102
// Subtle: will be zero for functions returning procedure pointers
103103
return symbol->Rank();
104104
}
@@ -116,7 +116,7 @@ int ProcedureDesignator::Rank() const {
116116
}
117117

118118
const Symbol *ProcedureDesignator::GetInterfaceSymbol() const {
119-
if (const Symbol * symbol{GetSymbol()}) {
119+
if (const Symbol *symbol{GetSymbol()}) {
120120
const Symbol &ultimate{symbol->GetUltimate()};
121121
if (const auto *proc{ultimate.detailsIf<semantics::ProcEntityDetails>()}) {
122122
return proc->procInterface();
@@ -131,9 +131,9 @@ const Symbol *ProcedureDesignator::GetInterfaceSymbol() const {
131131
}
132132

133133
bool ProcedureDesignator::IsElemental() const {
134-
if (const Symbol * interface{GetInterfaceSymbol()}) {
134+
if (const Symbol *interface{GetInterfaceSymbol()}) {
135135
return IsElementalProcedure(*interface);
136-
} else if (const Symbol * symbol{GetSymbol()}) {
136+
} else if (const Symbol *symbol{GetSymbol()}) {
137137
return IsElementalProcedure(*symbol);
138138
} else if (const auto *intrinsic{std::get_if<SpecificIntrinsic>(&u)}) {
139139
return intrinsic->characteristics.value().attrs.test(
@@ -145,9 +145,9 @@ bool ProcedureDesignator::IsElemental() const {
145145
}
146146

147147
bool ProcedureDesignator::IsPure() const {
148-
if (const Symbol * interface{GetInterfaceSymbol()}) {
148+
if (const Symbol *interface{GetInterfaceSymbol()}) {
149149
return IsPureProcedure(*interface);
150-
} else if (const Symbol * symbol{GetSymbol()}) {
150+
} else if (const Symbol *symbol{GetSymbol()}) {
151151
return IsPureProcedure(*symbol);
152152
} else if (const auto *intrinsic{std::get_if<SpecificIntrinsic>(&u)}) {
153153
return intrinsic->characteristics.value().attrs.test(
@@ -158,6 +158,20 @@ bool ProcedureDesignator::IsPure() const {
158158
return false;
159159
}
160160

161+
bool ProcedureDesignator::IsSimple() const {
162+
if (const Symbol *interface{GetInterfaceSymbol()}) {
163+
return IsSimpleProcedure(*interface);
164+
} else if (const Symbol *symbol{GetSymbol()}) {
165+
return IsSimpleProcedure(*symbol);
166+
} else if (const auto *intrinsic{std::get_if<SpecificIntrinsic>(&u)}) {
167+
return intrinsic->characteristics.value().attrs.test(
168+
characteristics::Procedure::Attr::Simple);
169+
} else {
170+
DIE("ProcedureDesignator::IsSimple(): no case");
171+
}
172+
return false;
173+
}
174+
161175
const SpecificIntrinsic *ProcedureDesignator::GetSpecificIntrinsic() const {
162176
return std::get_if<SpecificIntrinsic>(&u);
163177
}

0 commit comments

Comments
 (0)