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

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 14 10:12:23 PDT 2024


================
@@ -3922,6 +3922,42 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
     return true;
   }
 
+  const auto OldFX = Old->getFunctionEffects();
+  const auto NewFX = New->getFunctionEffects();
+  if (OldFX != NewFX) {
+    const auto Diffs = FunctionEffectSet::differences(OldFX, NewFX);
+    for (const auto &Item : Diffs) {
+      const FunctionEffect *Effect = Item.first;
+      const bool Adding = Item.second;
+      if (Effect->diagnoseRedeclaration(Adding, *Old, OldFX, *New, NewFX)) {
+        Diag(New->getLocation(),
+             diag::warn_mismatched_func_effect_redeclaration)
+            << Effect->name();
+        Diag(Old->getLocation(), diag::note_previous_declaration);
+      }
+    }
+
+    const auto MergedFX = OldFX | NewFX;
+
+    // Having diagnosed any problems, prevent further errors by applying the
+    // merged set of effects to both declarations.
+    auto applyMergedFX = [&](FunctionDecl *FD) {
+      const auto *FPT = FD->getType()->getAs<FunctionProtoType>();
+      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+      EPI.FunctionEffects = MergedFX;
+      QualType ModQT = Context.getFunctionType(FD->getReturnType(),
+                                               FPT->getParamTypes(), EPI);
+
+      FD->setType(ModQT);
+    };
+
+    applyMergedFX(Old);
+    applyMergedFX(New);
+
+    OldQType = Old->getType();
----------------
Sirraide wrote:

> In prototyping the feature, it was really helpful to be able to redeclare things like `pthread_self()` as `nolock`.

In that case, when determining whether a function should be treated as `nolock` during the analysis phase, one option would be to check all of its declarations and consider a function to be `nolock` if at least one of its declaration is `nolock`.

The problem I see w/ doing something here is that we don’t modify the `Old` declaration pretty much ever, from what I remember, so I’m somewhat wary of doing so breaking things in unforeseen ways, because the rest of the code base can currently assume that we don’t just go around changing function decls all the time—that said, I’m not *sure* doing so would break something, just a bit worried it might.

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


More information about the cfe-commits mailing list