summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-03-25 22:29:27 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-03-25 22:29:27 +0000
commit0e32c5283ae8307179da18ddeef112435bbcbf6b (patch)
tree0b3ba1688728b75a42328e3e7463f18c49a45e10 /clang/lib/Sema/SemaExpr.cpp
parent27fa77e102ae716869f0daa0c96c5f3c71772f7b (diff)
downloadbcm5719-llvm-0e32c5283ae8307179da18ddeef112435bbcbf6b.tar.gz
bcm5719-llvm-0e32c5283ae8307179da18ddeef112435bbcbf6b.zip
Don't warn on "use" of undefined inline function that isn't actually an ODR
use. In order for this to fire, the function needed to be a templated function marked 'constexpr' and declared but not defined. This weird pattern appears in libstdc++'s alloc_traits.h. llvm-svn: 264471
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp31
1 files changed, 16 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8b2ff757914..b93a568ebee 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12770,7 +12770,7 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) {
/// \brief Mark a function referenced, and check whether it is odr-used
/// (C++ [basic.def.odr]p2, C99 6.9p3)
void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
- bool OdrUse) {
+ bool MightBeOdrUse) {
assert(Func && "No function?");
Func->setReferenced();
@@ -12783,8 +12783,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
// We (incorrectly) mark overload resolution as an unevaluated context, so we
// can just check that here. Skip the rest of this function if we've already
// marked the function as used.
- if (Func->isUsed(/*CheckUsedAttr=*/false) ||
- !IsPotentiallyEvaluatedContext(*this)) {
+ bool OdrUse = MightBeOdrUse && IsPotentiallyEvaluatedContext(*this);
+ if (Func->isUsed(/*CheckUsedAttr=*/false) || !OdrUse) {
// C++11 [temp.inst]p3:
// Unless a function template specialization has been explicitly
// instantiated or explicitly specialized, the function template
@@ -12873,8 +12873,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
ResolveExceptionSpec(Loc, FPT);
- if (!OdrUse) return;
-
// Implicit instantiation of function templates and member functions of
// class templates.
if (Func->isImplicitlyInstantiable()) {
@@ -12922,10 +12920,12 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
// Walk redefinitions, as some of them may be instantiable.
for (auto i : Func->redecls()) {
if (!i->isUsed(false) && i->isImplicitlyInstantiable())
- MarkFunctionReferenced(Loc, i);
+ MarkFunctionReferenced(Loc, i, OdrUse);
}
}
+ if (!OdrUse) return;
+
// Keep track of used but undefined functions.
if (!Func->isDefined()) {
if (mightHaveNonExternalLinkage(Func))
@@ -13800,13 +13800,13 @@ void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
}
static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
- Decl *D, Expr *E, bool OdrUse) {
+ Decl *D, Expr *E, bool MightBeOdrUse) {
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
DoMarkVarDeclReferenced(SemaRef, Loc, Var, E);
return;
}
- SemaRef.MarkAnyDeclReferenced(Loc, D, OdrUse);
+ SemaRef.MarkAnyDeclReferenced(Loc, D, MightBeOdrUse);
// 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.
@@ -13828,7 +13828,7 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl);
if (!DM || DM->isPure())
return;
- SemaRef.MarkAnyDeclReferenced(Loc, DM, OdrUse);
+ SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse);
}
/// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
@@ -13851,30 +13851,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;
+ bool MightBeOdrUse = true;
if (E->performsVirtualDispatch(getLangOpts())) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl()))
if (Method->isPure())
- OdrUse = false;
+ MightBeOdrUse = false;
}
SourceLocation Loc = E->getMemberLoc().isValid() ?
E->getMemberLoc() : E->getLocStart();
- MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, OdrUse);
+ MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse);
}
/// \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 a
/// normal expression which refers to a variable.
-void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
- if (OdrUse) {
+void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D,
+ bool MightBeOdrUse) {
+ if (MightBeOdrUse) {
if (auto *VD = dyn_cast<VarDecl>(D)) {
MarkVariableReferenced(Loc, VD);
return;
}
}
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- MarkFunctionReferenced(Loc, FD, OdrUse);
+ MarkFunctionReferenced(Loc, FD, MightBeOdrUse);
return;
}
D->setReferenced();
OpenPOWER on IntegriCloud