================
@@ -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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to