Skip to content

Commit c942095

Browse files
committed
[OpenMP][FIX] Verify compatible types for declare variant calls
Especially for templates we need to check at some point if the base function matches the specialization we might call instead. Before this lead to the replacement of `std::sqrt(int(2))` calls with one that converts the argument to a `std::complex<int>`, clearly not the desired behavior. Reported as PR47655 Reviewed By: JonChesterfield Differential Revision: https://reviews.llvm.org/D88384
1 parent f3ead88 commit c942095

File tree

3 files changed

+279
-3
lines changed

3 files changed

+279
-3
lines changed

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5921,7 +5921,6 @@ void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
59215921
continue;
59225922

59235923
QualType UDeclTy = UDecl->getType();
5924-
// TODO: Verify types for templates eventually.
59255924
if (!UDeclTy->isDependentType()) {
59265925
QualType NewType = Context.mergeFunctionTypes(
59275926
FType, UDeclTy, /* OfBlockPointer */ false,
@@ -6009,6 +6008,8 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
60096008
TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
60106009
getCurFunctionDecl());
60116010

6011+
QualType CalleeFnType = CalleeFnDecl->getType();
6012+
60126013
SmallVector<Expr *, 4> Exprs;
60136014
SmallVector<VariantMatchInfo, 4> VMIs;
60146015
while (CalleeFnDecl) {
@@ -6061,8 +6062,19 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
60616062
}
60626063
NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
60636064
ExecConfig);
6064-
if (NewCall.isUsable())
6065-
break;
6065+
if (NewCall.isUsable()) {
6066+
if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6067+
FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6068+
QualType NewType = Context.mergeFunctionTypes(
6069+
CalleeFnType, NewCalleeFnDecl->getType(),
6070+
/* OfBlockPointer */ false,
6071+
/* Unqualified */ false, /* AllowCXX */ true);
6072+
if (!NewType.isNull())
6073+
break;
6074+
// Don't use the call if the function type was not compatible.
6075+
NewCall = nullptr;
6076+
}
6077+
}
60666078
}
60676079

60686080
VMIs.erase(VMIs.begin() + BestIdx);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ static void instantiateOMPDeclareVariantAttr(
444444
New->getLocation());
445445
if (!SubstFD)
446446
return;
447+
QualType NewType = S.Context.mergeFunctionTypes(
448+
SubstFD->getType(), FD->getType(),
449+
/* OfBlockPointer */ false,
450+
/* Unqualified */ false, /* AllowCXX */ true);
451+
if (NewType.isNull())
452+
return;
447453
S.InstantiateFunctionDefinition(
448454
New->getLocation(), SubstFD, /* Recursive */ true,
449455
/* DefinitionRequired */ false, /* AtEndOfTU */ false);

0 commit comments

Comments
 (0)