summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp19
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();
OpenPOWER on IntegriCloud