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

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 16 13:34:52 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:

I personally feel like the macro solution is ‘good enough’, if you will; I don’t think `CheckEquivalentExceptionSpec` modifies `Old`, so I’m not sure why that comment says is does—maybe it did at the time (the comment is from 2016, and, funnily enough, was also added in the same commit that introduced that call to `isFunctionConversion()` where the arguments seem transposed).

There is one place where we call `setDeletedAsWritten(false)` on the old decl in a caller of `MergeFunctionDecl()`, but that one has a FIXME next to it, so...

I’ll ask if anyone’s aware of any specific reasons why or ways in which we should avoid modifying `Old` here, and if not, then I’ll see if I can make the pointer `const`, because that would communicate the intent more clearly that it’s really not supposed to be modified.

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


More information about the cfe-commits mailing list