diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
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(); |