[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu May 16 06:16:43 PDT 2024
================
@@ -5028,3 +5060,263 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
getTypeConstraintConcept(), getTypeConstraintArguments());
}
+
+FunctionEffect::Kind FunctionEffect::oppositeKind() const {
+ switch (kind()) {
+ case Kind::NonBlocking:
+ return Kind::Blocking;
+ case Kind::Blocking:
+ return Kind::NonBlocking;
+ case Kind::NonAllocating:
+ return Kind::Allocating;
+ case Kind::Allocating:
+ return Kind::NonAllocating;
+ case Kind::None:
+ return Kind::None;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+StringRef FunctionEffect::name() const {
+ switch (kind()) {
+ case Kind::NonBlocking:
+ return "nonblocking";
+ case Kind::NonAllocating:
+ return "nonallocating";
+ case Kind::Blocking:
+ return "blocking";
+ case Kind::Allocating:
+ return "allocating";
+ case Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+bool FunctionEffect::canInferOnFunction(const Decl &Callee) const {
+ switch (kind()) {
+ case Kind::NonAllocating:
+ case Kind::NonBlocking: {
+ FunctionEffectsRef CalleeFX;
+ if (auto *FD = Callee.getAsFunction())
+ CalleeFX = FD->getFunctionEffects();
+ else if (auto *BD = dyn_cast<BlockDecl>(&Callee))
+ CalleeFX = BD->getFunctionEffects();
+ else
+ return false;
+ for (const FunctionEffectWithCondition &CalleeEC : CalleeFX) {
+ // nonblocking/nonallocating cannot call allocating
+ if (CalleeEC.Effect.kind() == Kind::Allocating)
+ return false;
+ // nonblocking cannot call blocking
+ if (kind() == Kind::NonBlocking &&
+ CalleeEC.Effect.kind() == Kind::Blocking)
+ return false;
+ }
+ }
+ return true;
+
+ case Kind::Allocating:
+ case Kind::Blocking:
+ return false;
+
+ case Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+bool FunctionEffect::shouldDiagnoseFunctionCall(
+ bool Direct, ArrayRef<FunctionEffect> CalleeFX) const {
+ switch (kind()) {
+ case Kind::NonAllocating:
+ case Kind::NonBlocking: {
+ const Kind CallerKind = kind();
+ for (const auto &Effect : CalleeFX) {
+ const Kind EK = Effect.kind();
+ // Does callee have same or stronger constraint?
+ if (EK == CallerKind ||
+ (CallerKind == Kind::NonAllocating && EK == Kind::NonBlocking)) {
+ return false; // no diagnostic
+ }
+ }
+ return true; // warning
+ }
+ case Kind::Allocating:
+ case Kind::Blocking:
+ return false;
+ case Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+// =====
+
+void FunctionEffectsRef::Profile(llvm::FoldingSetNodeID &ID) const {
+ const bool HasConds = !Conditions.empty();
+
+ ID.AddInteger(size() | (HasConds << 31u));
+ for (unsigned Idx = 0, Count = Effects.size(); Idx != Count; ++Idx) {
+ ID.AddInteger(Effects[Idx].toOpaqueInt32());
+ if (HasConds)
+ ID.AddPointer(Conditions[Idx].expr());
+ }
+}
+
+void FunctionEffectSet::insert(const FunctionEffectWithCondition &NewEC,
+ Conflicts &Errs) {
+ const FunctionEffect::Kind NewOppositeKind = NewEC.Effect.oppositeKind();
----------------
AaronBallman wrote:
```suggestion
FunctionEffect::Kind NewOppositeKind = NewEC.Effect.oppositeKind();
```
https://github.com/llvm/llvm-project/pull/84983
More information about the cfe-commits
mailing list