diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-10-20 01:38:33 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-10-20 01:38:33 +0000 |
| commit | 5016a70c183a50845a0421802d161093dd0643f6 (patch) | |
| tree | f06564c7146ab4ad5e59659dc1b67741c07e2b17 /lib/CodeGen/CGExpr.cpp | |
| parent | 0872a06d1ee1a3b62ef833f955051418d18006a1 (diff) | |
DR1472: A reference isn't odr-used if it has preceding initialization,
initialized by a reference constant expression.
Our odr-use modeling still needs work here: we don't yet implement the 'set of
potential results of an expression' DR.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166361 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 809c1c1517..8af1889a6a 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/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?"); |
