[clang] [clang] Diagnose default arguments defined in different scopes (PR #124844)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 29 01:35:53 PST 2025
================
@@ -5810,6 +5810,62 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {
return false;
}
+/// @brief Checks that each default argument needed to make the call
+/// is defined only once, implementing [over.match.best]/4 rule.
+///
+/// @param FDecl Function declaration selected for the call
+/// @param NumArgs Number of argument explicitly specified in the call
+/// expression
+/// @param CallLoc Source location of the call expression
+static void checkDefaultArgumentsAcrossScopes(Sema &S, FunctionDecl *FDecl,
+ int NumArgs,
+ SourceLocation CallLoc) {
+ // [over.match.best]/4:
+ // If the best viable function resolves to a function
+ // for which multiple declarations were found,
+ // and if any two of these declarations inhabit different scopes
+ // and specify a default argument that made the function viable,
+ // the program is ill-formed.
+
+ // Calculate the range of parameters,
+ // default arguments of which made the candidate viable.
+ int FirstDefaultArgIndex = NumArgs;
+ int LastDefaultArgIndex = FDecl->getNumParams() - 1;
+
+ // For each such parameter, collect all redeclarations
+ // that have non-inherited default argument.
+ llvm::SmallDenseMap<int, llvm::TinyPtrVector<ParmVarDecl *>> ParamRedecls(
+ LastDefaultArgIndex - FirstDefaultArgIndex + 1);
+ for (FunctionDecl *Redecl : FDecl->redecls()) {
+ for (int i = FirstDefaultArgIndex; i <= LastDefaultArgIndex; ++i) {
+ ParmVarDecl *Param = Redecl->getParamDecl(i);
+ if (Param->hasDefaultArg() && !Param->hasInheritedDefaultArg())
+ ParamRedecls[i].push_back(Param);
+ }
+ }
----------------
cor3ntin wrote:
If you iterate over `i` in the outer loop, you can forgo the map entirely and do it on one pass
https://github.com/llvm/llvm-project/pull/124844
More information about the cfe-commits
mailing list