summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp22
-rw-r--r--clang/lib/Sema/SemaOverload.cpp22
2 files changed, 24 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 80df07630e1..8016bf99889 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14665,24 +14665,24 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
ME->performsVirtualDispatch(SemaRef.getLangOpts());
if (!IsVirtualCall)
return;
- const Expr *Base = ME->getBase();
- const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType();
- if (!MostDerivedClassDecl)
- return;
- CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl);
- if (!DM || DM->isPure())
- return;
- SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse);
+
+ // If it's possible to devirtualize the call, mark the called function
+ // referenced.
+ CXXMethodDecl *DM = MD->getDevirtualizedMethod(
+ ME->getBase(), SemaRef.getLangOpts().AppleKext);
+ if (DM)
+ SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse);
}
/// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
-void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
+void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
// TODO: update this with DR# once a defect report is filed.
// C++11 defect. The address of a pure member should not be an ODR use, even
// if it's a qualified reference.
bool OdrUse = true;
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getDecl()))
- if (Method->isVirtual())
+ if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getDecl()))
+ if (Method->isVirtual() &&
+ !Method->getDevirtualizedMethod(Base, getLangOpts().AppleKext))
OdrUse = false;
MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse);
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index afa9cd88ca8..36f24fd9c46 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -48,7 +48,7 @@ static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) {
/// A convenience routine for creating a decayed reference to a function.
static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
- bool HadMultipleCandidates,
+ const Expr *Base, bool HadMultipleCandidates,
SourceLocation Loc = SourceLocation(),
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
@@ -68,7 +68,7 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
if (HadMultipleCandidates)
DRE->setHadMultipleCandidates(true);
- S.MarkDeclRefReferenced(DRE);
+ S.MarkDeclRefReferenced(DRE, Base);
return S.ImpCastExprToType(DRE, S.Context.getPointerType(DRE->getType()),
CK_FunctionToPointerDecay);
}
@@ -11946,6 +11946,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
FunctionDecl *FnDecl = Best->Function;
if (FnDecl) {
+ Expr *Base = nullptr;
// We matched an overloaded operator. Build a call to that
// operator.
@@ -11958,7 +11959,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
Best->FoundDecl, Method);
if (InputRes.isInvalid())
return ExprError();
- Input = InputRes.get();
+ Base = Input = InputRes.get();
} else {
// Convert the arguments.
ExprResult InputInit
@@ -11974,7 +11975,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
// Build the actual expression node.
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl,
- HadMultipleCandidates, OpLoc);
+ Base, HadMultipleCandidates,
+ OpLoc);
if (FnExpr.isInvalid())
return ExprError();
@@ -12159,6 +12161,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
FunctionDecl *FnDecl = Best->Function;
if (FnDecl) {
+ Expr *Base = nullptr;
// We matched an overloaded operator. Build a call to that
// operator.
@@ -12180,7 +12183,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
- Args[0] = Arg0.getAs<Expr>();
+ Base = Args[0] = Arg0.getAs<Expr>();
Args[1] = RHS = Arg1.getAs<Expr>();
} else {
// Convert the arguments.
@@ -12204,7 +12207,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Build the actual expression node.
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
- Best->FoundDecl,
+ Best->FoundDecl, Base,
HadMultipleCandidates, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
@@ -12426,6 +12429,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
Best->FoundDecl,
+ Base,
HadMultipleCandidates,
OpLocInfo.getLoc(),
OpLocInfo.getInfo());
@@ -12984,7 +12988,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc);
OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc));
ExprResult NewFn = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
- HadMultipleCandidates,
+ Obj, HadMultipleCandidates,
OpLocInfo.getLoc(),
OpLocInfo.getInfo());
if (NewFn.isInvalid())
@@ -13175,7 +13179,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
// Build the operator call.
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
- HadMultipleCandidates, OpLoc);
+ Base, HadMultipleCandidates, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
@@ -13234,7 +13238,7 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
FunctionDecl *FD = Best->Function;
ExprResult Fn = CreateFunctionRefExpr(*this, FD, Best->FoundDecl,
- HadMultipleCandidates,
+ nullptr, HadMultipleCandidates,
SuffixInfo.getLoc(),
SuffixInfo.getInfo());
if (Fn.isInvalid())
OpenPOWER on IntegriCloud