aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2013-02-02 00:25:55 +0000
committerNick Lewycky <nicholas@mxc.ca>2013-02-02 00:25:55 +0000
commitb7e5eec2f57bd82c6ddb762ca3dd7b7d8697e9d5 (patch)
tree7888570249ff2e98a75a4a6ec5ca6d4f6171e256 /lib/Sema/SemaExpr.cpp
parent0c4394c7f63008fbf4d335710b34f71afab362a3 (diff)
This patch makes "&Cls::purevfn" not an odr use. This isn't what the standard
says, but that's a defect (to be filed). "Cls::purevfn()" is still an odr use. Also fixes a bug that caused us to not mark the function referenced just because we didn't want to mark it odr used. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174242 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp43
1 files changed, 28 insertions, 15 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2167f01b63..0465707e7c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2025,7 +2025,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
if (SelfExpr.isInvalid())
return ExprError();
- MarkAnyDeclReferenced(Loc, IV);
+ MarkAnyDeclReferenced(Loc, IV, true);
ObjCMethodFamily MF = CurMethod->getMethodFamily();
if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize)
@@ -11152,13 +11152,13 @@ void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
}
static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
- Decl *D, Expr *E) {
+ Decl *D, Expr *E, bool OdrUse) {
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
DoMarkVarDeclReferenced(SemaRef, Loc, Var, E);
return;
}
- SemaRef.MarkAnyDeclReferenced(Loc, D);
+ SemaRef.MarkAnyDeclReferenced(Loc, D, OdrUse);
// If this is a call to a method via a cast, also mark the method in the
// derived class used in case codegen can devirtualize the call.
@@ -11175,12 +11175,19 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl);
if (!DM)
return;
- SemaRef.MarkAnyDeclReferenced(Loc, DM);
+ SemaRef.MarkAnyDeclReferenced(Loc, DM, OdrUse);
}
/// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
- MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
+ // 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->isPure())
+ OdrUse = false;
+ MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse);
}
/// \brief Perform reference-marking and odr-use handling for a MemberExpr.
@@ -11191,25 +11198,31 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
// 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.
+ bool OdrUse = true;
if (!E->hasQualifier()) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl()))
if (Method->isPure())
- return;
+ OdrUse = false;
}
- MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E);
+ MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E, OdrUse);
}
/// \brief Perform marking for a reference to an arbitrary declaration. It
/// marks the declaration referenced, and performs odr-use checking for functions
/// and variables. This method should not be used when building an normal
/// expression which refers to a variable.
-void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D) {
- if (VarDecl *VD = dyn_cast<VarDecl>(D))
- MarkVariableReferenced(Loc, VD);
- else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- MarkFunctionReferenced(Loc, FD);
- else
- D->setReferenced();
+void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
+ if (OdrUse) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ MarkVariableReferenced(Loc, VD);
+ return;
+ }
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ MarkFunctionReferenced(Loc, FD);
+ return;
+ }
+ }
+ D->setReferenced();
}
namespace {
@@ -11234,7 +11247,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument(
const TemplateArgument &Arg) {
if (Arg.getKind() == TemplateArgument::Declaration) {
if (Decl *D = Arg.getAsDecl())
- S.MarkAnyDeclReferenced(Loc, D);
+ S.MarkAnyDeclReferenced(Loc, D, true);
}
return Inherited::TraverseTemplateArgument(Arg);