================
@@ -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();
----------------
dougsonos wrote:

> > A workaround would be to create wrapper functions that are declared safe 
> > but call the unsafe function with diagnostics disabled.
> 
> I could see there being situations where you might want to be able to do 
> something like that (i.e. declare a function as safe even if the compiler 
> might think it’s unsafe because it calls unsafe functions), but I wonder if 
> you couldn’t just disable the diagnostics locally in that function (or even 
> just parts thereof) only using a `#pragma`.

Yes, though that could make it difficult to distinguish between
- calls that are truly unsafe but where disabling warnings is needed in the 
short term
- calls that are truly safe but where annotation hasn't yet caught up (e.g. 
https://developer.apple.com/documentation/kernel/1532191-vdsp_vadd )

On the other hand, it is practical to disable diagnostics through a macro 
including pragmas. The user could employ two different macros to disable 
diagnostics, and the macro names would express the difference between the two 
situations.

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