diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-06-11 17:50:32 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-06-11 17:50:32 +0000 |
commit | 715f7a1bd058c64a39cc4773114dfb46ae8cc8a3 (patch) | |
tree | d9f4369bedcbe50c9dc03ee5498544702d86616e /clang/lib/CodeGen | |
parent | ef2d6d99c0d35e46dce7fff6b999a3a1fc08aecc (diff) | |
download | bcm5719-llvm-715f7a1bd058c64a39cc4773114dfb46ae8cc8a3.tar.gz bcm5719-llvm-715f7a1bd058c64a39cc4773114dfb46ae8cc8a3.zip |
For DR712: store on a DeclRefExpr whether it constitutes an odr-use.
Begin restructuring to support the forms of non-odr-use reference
permitted by DR712.
llvm-svn: 363086
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 19 |
2 files changed, 15 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 61f9de9a292..db18ac49c6e 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1783,8 +1783,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { } llvm::Constant *constant = nullptr; - if (emission.IsConstantAggregate || D.isConstexpr() || - D.isUsableInConstantExpressions(getContext())) { + if (emission.IsConstantAggregate || + D.mightBeUsableInConstantExpressions(getContext())) { assert(!capturedByInit && "constant init contains a capturing block?"); constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D); if (constant && !constant->isZeroValue() && diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5b576555146..46b1af5e1cf 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1398,7 +1398,7 @@ static bool isConstantEmittableObjectType(QualType type) { /// Can we constant-emit a load of a reference to a variable of the /// given type? This is different from predicates like -/// Decl::isUsableInConstantExpressions because we do want it to apply +/// Decl::mightBeUsableInConstantExpressions because we do want it to apply /// in situations that don't necessarily satisfy the language's rules /// for this (e.g. C++'s ODR-use rules). For example, we want to able /// to do this with const float variables even if those variables @@ -1492,11 +1492,17 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) { static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF, const MemberExpr *ME) { if (auto *VD = dyn_cast<VarDecl>(ME->getMemberDecl())) { + // FIXME: Copy this from the MemberExpr once we store it there. + NonOdrUseReason NOUR = NOUR_None; + if (VD->getType()->isReferenceType() && + VD->isUsableInConstantExpressions(CGF.getContext())) + NOUR = NOUR_Constant; + // Try to emit static variable member expressions as DREs. return DeclRefExpr::Create( CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD, /*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(), - ME->getType(), ME->getValueKind()); + ME->getType(), ME->getValueKind(), nullptr, nullptr, NOUR); } return nullptr; } @@ -2462,12 +2468,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // A DeclRefExpr for a reference initialized by a constant expression can // appear without being odr-used. Directly emit the constant initializer. - const Expr *Init = VD->getAnyInitializer(VD); + VD->getAnyInitializer(VD); const auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl); - if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() && - VD->isUsableInConstantExpressions(getContext()) && - VD->checkInitIsICE() && + if (E->isNonOdrUse() == NOUR_Constant && VD->getType()->isReferenceType() && // Do not emit if it is private OpenMP variable. + // FIXME: This should be handled in odr-use marking, not here. !(E->refersToEnclosingVariableOrCapture() && ((CapturedStmtInfo && (LocalDeclMap.count(VD->getCanonicalDecl()) || @@ -2489,6 +2494,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl); } + // FIXME: Handle other kinds of non-odr-use DeclRefExprs. + // Check for captured variables. if (E->refersToEnclosingVariableOrCapture()) { VD = VD->getCanonicalDecl(); |