================ @@ -2743,3 +2759,153 @@ bool Sema::isDeclaratorFunctionLike(Declarator &D) { }); return Result; } + +FunctionEffectDifferences::FunctionEffectDifferences( + const FunctionEffectsRef &Old, const FunctionEffectsRef &New) { + + FunctionEffectsRef::iterator POld = Old.begin(); + FunctionEffectsRef::iterator OldEnd = Old.end(); + FunctionEffectsRef::iterator PNew = New.begin(); + FunctionEffectsRef::iterator NewEnd = New.end(); + + while (true) { + int cmp = 0; + if (POld == OldEnd) { + if (PNew == NewEnd) + break; + cmp = 1; + } else if (PNew == NewEnd) + cmp = -1; + else { + FunctionEffectWithCondition Old = *POld; + FunctionEffectWithCondition New = *PNew; + if (Old.Effect.kind() < New.Effect.kind()) + cmp = -1; + else if (New.Effect.kind() < Old.Effect.kind()) + cmp = 1; + else { + cmp = 0; + if (Old.Cond.expr() != New.Cond.expr()) { + // TODO: Cases where the expressions are equivalent but + // don't have the same identity. + push_back(FunctionEffectDiff{ + Old.Effect.kind(), FunctionEffectDiff::Kind::ConditionMismatch, + Old, New}); + } + } + } + + if (cmp < 0) { + // removal + FunctionEffectWithCondition Old = *POld; + push_back(FunctionEffectDiff{ + Old.Effect.kind(), FunctionEffectDiff::Kind::Removed, Old, {}}); + ++POld; + } else if (cmp > 0) { + // addition + FunctionEffectWithCondition New = *PNew; + push_back(FunctionEffectDiff{ + New.Effect.kind(), FunctionEffectDiff::Kind::Added, {}, New}); + ++PNew; + } else { + ++POld; + ++PNew; + } + } +} + +bool FunctionEffectDiff::shouldDiagnoseConversion( + QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType, + const FunctionEffectsRef &DstFX) const { + + switch (EffectKind) { + case FunctionEffect::Kind::NonAllocating: + // nonallocating can't be added (spoofed) during a conversion, unless we + // have nonblocking + if (DiffKind == Kind::Added) { + for (const auto &CFE : SrcFX) { + if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking) + return false; + } + } + [[fallthrough]]; + case FunctionEffect::Kind::NonBlocking: + // nonblocking can't be added (spoofed) during a conversion. + switch (DiffKind) { + case Kind::Added: + return true; + case Kind::Removed: + return false; + case Kind::ConditionMismatch: + // TODO: Condition mismatches are too coarse right now -- expressions ---------------- AaronBallman wrote:
```suggestion // FIXME: Condition mismatches are too coarse right now -- expressions ``` 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