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.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 809c1c15177..8af1889a6a1 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1695,6 +1695,21 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
CharUnits Alignment = getContext().getDeclAlign(ND);
QualType T = E->getType();
+ // A DeclRefExpr for a reference initialized by a constant expression can
+ // appear without being odr-used. Directly emit the constant initializer.
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ const Expr *Init = VD->getAnyInitializer(VD);
+ if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
+ VD->isUsableInConstantExpressions(getContext()) &&
+ VD->checkInitIsICE()) {
+ llvm::Constant *Val =
+ CGM.EmitConstantValue(*VD->evaluateValue(), VD->getType(), this);
+ assert(Val && "failed to emit reference constant expression");
+ // FIXME: Eventually we will want to emit vector element references.
+ return MakeAddrLValue(Val, T, Alignment);
+ }
+ }
+
// FIXME: We should be able to assert this for FunctionDecls as well!
// FIXME: We should be able to assert this for all DeclRefExprs, not just
// those with a valid source location.
@@ -1705,7 +1720,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
if (ND->hasAttr<WeakRefAttr>()) {
const ValueDecl *VD = cast<ValueDecl>(ND);
llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
- return MakeAddrLValue(Aliasee, E->getType(), Alignment);
+ return MakeAddrLValue(Aliasee, T, Alignment);
}
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
@@ -1733,9 +1748,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal());
- CharUnits alignment = getContext().getDeclAlign(VD);
return MakeAddrLValue(GetAddrOfBlockDecl(VD, isBlockVariable),
- E->getType(), alignment);
+ T, Alignment);
}
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
OpenPOWER on IntegriCloud