[clang] nolock/noalloc attributes (PR #84983)

Doug Wyatt via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 13 09:05:02 PDT 2024


================
@@ -4912,3 +4922,279 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
   Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
           getTypeConstraintConcept(), getTypeConstraintArguments());
 }
+
+FunctionEffect::~FunctionEffect() = default;
+
+bool FunctionEffect::diagnoseConversion(bool Adding, QualType OldType,
+                                        FunctionEffectSet OldFX,
+                                        QualType NewType,
+                                        FunctionEffectSet NewFX) const {
+  return false;
+}
+
+bool FunctionEffect::diagnoseRedeclaration(bool Adding,
+                                           const FunctionDecl &OldFunction,
+                                           FunctionEffectSet OldFX,
+                                           const FunctionDecl &NewFunction,
+                                           FunctionEffectSet NewFX) const {
+  return false;
+}
+
+bool FunctionEffect::diagnoseMethodOverride(bool Adding,
+                                            const CXXMethodDecl &OldMethod,
+                                            FunctionEffectSet OldFX,
+                                            const CXXMethodDecl &NewMethod,
+                                            FunctionEffectSet NewFX) const {
+  return false;
+}
+
+bool FunctionEffect::canInferOnDecl(const Decl *Caller,
+                                    FunctionEffectSet CallerFX) const {
+  return false;
+}
+
+bool FunctionEffect::diagnoseFunctionCall(bool Direct, const Decl *Caller,
+                                          FunctionEffectSet CallerFX,
+                                          CalleeDeclOrType Callee,
+                                          FunctionEffectSet CalleeFX) const {
+  return false;
+}
+
+const NoLockNoAllocEffect &NoLockNoAllocEffect::nolock_instance() {
+  static NoLockNoAllocEffect global(kNoLockTrue, "nolock");
+  return global;
+}
----------------
dougsonos wrote:

I did one whole implementation with both the true/false forms of the attributes as `AttributedType`. Along the way I found and had to hack around two bugs where the sugar gets stripped, e.g. on an `auto` lambda.

I got some guidance that the `true` forms of the attributes made sense as part of the canonical type, so (confusingly, I know):
- the `true` attribute triggers the addition of a global instance of a `NoLockNoAllocEffect` into a `FunctionEffectSet` as an optional part of the `FunctionProtoType`. It does not currently put an attribute on the type.
- the `false` attribute uses `AttributedType`. BTW another limitation of `AttributedType` is that it doesn't seem to hold anything more than the attribute kind, so if we went that way we'd probably need 3 kinds for `nolock` (true, false, type-dependent expression) and 3 for `noalloc`. The type-dependent expression might end up needing a whole new type-sugar class.

Even if `FunctionEffect` turns out to be just some bits controlling details of the behavior, rather than a vtable, it's still attractive to me to encapsulate it into a uniqued object with methods, to centralize all those behaviors.

There's a fair amount of code prepared for the possibility of new, unrelated effects (e.g. "TCB + types"), anticipating that FunctionEffectSet could hold multiple effects. Considering for example a codebase that with several TCB's, they would all have the same behaviors about calls within themselves, but need to be considered unique effects, e.g. a function in TCB A can't call a function that's only part of TCB Z. This is the motivation for the FunctionEffect abstraction.

https://github.com/llvm/llvm-project/pull/84983


More information about the cfe-commits mailing list