[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
Doug Wyatt via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 23 13:46:51 PDT 2024
================
@@ -5016,3 +5041,345 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
getTypeConstraintConcept(), getTypeConstraintArguments());
}
+
+StringRef FunctionEffect::name() const {
+ switch (kind()) {
+ case Kind::NonBlocking:
+ return "nonblocking";
+ case Kind::NonAllocating:
+ return "nonallocating";
+ case Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+bool FunctionEffectDiff::shouldDiagnoseConversion(
+ QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType,
+ const FunctionEffectsRef &DstFX) const {
+
+ switch (EffectKind) {
+ case FunctionEffect::Kind::NonAllocating:
+ // nonallocating can't be added (spoofed) during a conversion, unless we
+ // have nonblocking
+ if (DiffKind == Kind::Added) {
+ for (const auto &CFE : SrcFX) {
+ if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking)
+ return false;
+ }
+ }
+ [[fallthrough]];
+ case FunctionEffect::Kind::NonBlocking:
+ // nonblocking can't be added (spoofed) during a conversion.
+ switch (DiffKind) {
+ case Kind::Added:
+ return true;
+ case Kind::Removed:
+ return false;
+ case Kind::AssertToDeny:
+ // effect asserted -> denied: no diagnostic.
+ return false;
+ case Kind::DenyToAssert:
+ // effect denied -> asserted: diagnose.
+ return true;
+ case Kind::ConditionMismatch:
+ return true; // TODO: ???
+ }
+ case FunctionEffect::Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+bool FunctionEffectDiff::shouldDiagnoseRedeclaration(
+ const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX,
+ const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const {
+ switch (EffectKind) {
+ case FunctionEffect::Kind::NonAllocating:
+ case FunctionEffect::Kind::NonBlocking:
+ // nonblocking/nonallocating can't be removed in a redeclaration
+ switch (DiffKind) {
+ case Kind::Added:
+ return false; // No diagnostic.
+ case Kind::Removed:
+ return true; // Issue diagnostic
+ case Kind::DenyToAssert:
+ case Kind::AssertToDeny:
+ case Kind::ConditionMismatch:
+ // All these forms of mismatches are diagnosed.
+ return true;
+ }
+ case FunctionEffect::Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+FunctionEffectDiff::OverrideResult
+FunctionEffectDiff::shouldDiagnoseMethodOverride(
+ const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX,
+ const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const {
+ switch (EffectKind) {
+ case FunctionEffect::Kind::NonAllocating:
+ case FunctionEffect::Kind::NonBlocking:
+ switch (DiffKind) {
+
+ // If added on an override, that's fine and not diagnosed.
+ case Kind::Added:
+ return OverrideResult::NoAction;
+
+ // If missing from an override (removed), propagate from base to derived.
+ case Kind::Removed:
+ return OverrideResult::MergeAdded;
+
+ // If there's a mismatch involving the effect's polarity or condition,
+ // issue a warning.
+ case Kind::DenyToAssert:
+ case Kind::AssertToDeny:
+ case Kind::ConditionMismatch:
+ return OverrideResult::Warn;
+ }
+
+ case FunctionEffect::Kind::None:
+ break;
+ }
+ llvm_unreachable("unknown effect kind");
+}
+
+bool FunctionEffect::canInferOnFunction(const Decl &Callee) const {
+ switch (kind()) {
+ case Kind::NonAllocating:
+ case Kind::NonBlocking:
+ // Do any of the callee's Decls have type sugar for blocking or allocating?
+ for (const Decl *D : Callee.redecls()) {
+ QualType QT;
+ if (auto *FD = D->getAsFunction()) {
+ QT = FD->getType();
+ } else if (auto *BD = dyn_cast<BlockDecl>(D)) {
+ if (auto *TSI = BD->getSignatureAsWritten())
+ QT = TSI->getType();
+ else
+ continue;
+ } else
+ continue;
+
+ // c.f. Sema::getCallingConvAttributedType
+ const AttributedType *AT = QT->getAs<AttributedType>();
----------------
dougsonos wrote:
TODO: update this for an all-canonical implementation
https://github.com/llvm/llvm-project/pull/84983
More information about the cfe-commits
mailing list