aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2013-01-31 01:34:31 +0000
committerNick Lewycky <nicholas@mxc.ca>2013-01-31 01:34:31 +0000
commit4ceaf337be78fa89b4a97f351be6d0bda962d7de (patch)
tree7cb4e0f160c91fd6bc3dbaebe6775ac4f5fb7f77 /lib/Sema/SemaExpr.cpp
parent5255f27362ffbfedea889870bf8d5812dae97553 (diff)
Fix ODR-use of a MemberExpr to check before marking a pure function used. Remove
a workaround for this bug from the -Wundefined-internals warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 60e104cadf..bfbb22ca08 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -10506,8 +10506,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
}
// Keep track of used but undefined functions.
- if (!Func->isPure() && !Func->hasBody() &&
- Func->getLinkage() != ExternalLinkage) {
+ if (!Func->isDefined() && Func->getLinkage() != ExternalLinkage) {
SourceLocation &old = UndefinedInternals[Func->getCanonicalDecl()];
if (old.isInvalid()) old = Loc;
}
@@ -11167,6 +11166,17 @@ void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
/// \brief Perform reference-marking and odr-use handling for a MemberExpr.
void Sema::MarkMemberReferenced(MemberExpr *E) {
+ // C++11 [basic.def.odr]p2
+ // A non-overloaded function whose name appears as a potentially-evaluated
+ // expression or a member of a set of candidate functions, if selected by
+ // overload resolution when referred to from a potentially-evaluated
+ // expression, is odr-used, unless it is a pure virtual function and its
+ // name is not explicitly qualified.
+ if (!E->hasQualifier()) {
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl()))
+ if (Method->isPure())
+ return;
+ }
MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E);
}