[clang] nolock/noalloc attributes (PR #84983)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 18 08:08:12 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 think that `foo()` ought to get verified because by the time verification happens, the redeclaration has been seen.
I agree that that would make sense.
> `MergeFunctionDecl` is unhappy that `New` has a different canonical type.
Iirc we’re adjusting the type(s) here for the purposes of the comparison only (there’s a `NewQTypeForComparison` or whatever it’s called); you may have to change either that (e.g. always drop the noalloc/nolock attributes from the new type or add them if only the old type has them) or possibly even do the same for the `OldQType` (i.e. introduce an `OldQTypeForComparison` and modify that one if necessary); that’s fine because those types are only for comparing the function types (as the name would suggest); the actual type of the declarations isn’t changed.
https://github.com/llvm/llvm-project/pull/84983
More information about the cfe-commits
mailing list