@@ -1259,6 +1259,43 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
12591259 if ((OldTemplate == nullptr) != (NewTemplate == nullptr))
12601260 return true;
12611261
1262+ if (NewTemplate) {
1263+ // C++ [temp.over.link]p4:
1264+ // The signature of a function template consists of its function
1265+ // signature, its return type and its template parameter list. The names
1266+ // of the template parameters are significant only for establishing the
1267+ // relationship between the template parameters and the rest of the
1268+ // signature.
1269+ //
1270+ // We check the return type and template parameter lists for function
1271+ // templates first; the remaining checks follow.
1272+ bool SameTemplateParameterList = SemaRef.TemplateParameterListsAreEqual(
1273+ NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate,
1274+ OldTemplate->getTemplateParameters(), false, Sema::TPL_TemplateMatch);
1275+ bool SameReturnType = SemaRef.Context.hasSameType(
1276+ Old->getDeclaredReturnType(), New->getDeclaredReturnType());
1277+ // FIXME(GH58571): Match template parameter list even for non-constrained
1278+ // template heads. This currently ensures that the code prior to C++20 is
1279+ // not newly broken.
1280+ bool ConstraintsInTemplateHead =
1281+ NewTemplate->getTemplateParameters()->hasAssociatedConstraints() ||
1282+ OldTemplate->getTemplateParameters()->hasAssociatedConstraints();
1283+ // C++ [namespace.udecl]p11:
1284+ // The set of declarations named by a using-declarator that inhabits a
1285+ // class C does not include member functions and member function
1286+ // templates of a base class that "correspond" to (and thus would
1287+ // conflict with) a declaration of a function or function template in
1288+ // C.
1289+ // Comparing return types is not required for the "correspond" check to
1290+ // decide whether a member introduced by a shadow declaration is hidden.
1291+ if (UseMemberUsingDeclRules && ConstraintsInTemplateHead &&
1292+ !SameTemplateParameterList)
1293+ return true;
1294+ if (!UseMemberUsingDeclRules &&
1295+ (!SameTemplateParameterList || !SameReturnType))
1296+ return true;
1297+ }
1298+
12621299 // Is the function New an overload of the function Old?
12631300 QualType OldQType = SemaRef.Context.getCanonicalType(Old->getType());
12641301 QualType NewQType = SemaRef.Context.getCanonicalType(New->getType());
@@ -1410,43 +1447,6 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
14101447 }
14111448 }
14121449
1413- if (NewTemplate) {
1414- // C++ [temp.over.link]p4:
1415- // The signature of a function template consists of its function
1416- // signature, its return type and its template parameter list. The names
1417- // of the template parameters are significant only for establishing the
1418- // relationship between the template parameters and the rest of the
1419- // signature.
1420- //
1421- // We check the return type and template parameter lists for function
1422- // templates first; the remaining checks follow.
1423- bool SameTemplateParameterList = SemaRef.TemplateParameterListsAreEqual(
1424- NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate,
1425- OldTemplate->getTemplateParameters(), false, Sema::TPL_TemplateMatch);
1426- bool SameReturnType = SemaRef.Context.hasSameType(
1427- Old->getDeclaredReturnType(), New->getDeclaredReturnType());
1428- // FIXME(GH58571): Match template parameter list even for non-constrained
1429- // template heads. This currently ensures that the code prior to C++20 is
1430- // not newly broken.
1431- bool ConstraintsInTemplateHead =
1432- NewTemplate->getTemplateParameters()->hasAssociatedConstraints() ||
1433- OldTemplate->getTemplateParameters()->hasAssociatedConstraints();
1434- // C++ [namespace.udecl]p11:
1435- // The set of declarations named by a using-declarator that inhabits a
1436- // class C does not include member functions and member function
1437- // templates of a base class that "correspond" to (and thus would
1438- // conflict with) a declaration of a function or function template in
1439- // C.
1440- // Comparing return types is not required for the "correspond" check to
1441- // decide whether a member introduced by a shadow declaration is hidden.
1442- if (UseMemberUsingDeclRules && ConstraintsInTemplateHead &&
1443- !SameTemplateParameterList)
1444- return true;
1445- if (!UseMemberUsingDeclRules &&
1446- (!SameTemplateParameterList || !SameReturnType))
1447- return true;
1448- }
1449-
14501450 if (!UseOverrideRules) {
14511451 Expr *NewRC = New->getTrailingRequiresClause(),
14521452 *OldRC = Old->getTrailingRequiresClause();
0 commit comments