From 6cc8317c38b8fd9b4debeabf5d28aa128bb61160 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Fri, 25 Aug 2017 10:07:00 +0000 Subject: [IRGen] Evaluate constant static variables referenced through member expressions C++ allows us to reference static variables through member expressions. Prior to this commit, non-integer static variables that were referenced using a member expression were always emitted using lvalue loads. The old behaviour introduced an inconsistency between regular uses of static variables and member expressions uses. For example, the following program compiled and linked successfully: struct Foo { constexpr static const char *name = "foo"; }; int main() { return Foo::name[0] == 'f'; } but this program failed to link because "Foo::name" wasn't found: struct Foo { constexpr static const char *name = "foo"; }; int main() { Foo f; return f.name[0] == 'f'; } This commit ensures that constant static variables referenced through member expressions are emitted in the same way as ordinary static variable references. rdar://33942261 Differential Revision: https://reviews.llvm.org/D36876 llvm-svn: 311772 --- clang/lib/CodeGen/CGExprComplex.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'clang/lib/CodeGen/CGExprComplex.cpp') diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 980972370dc..f019e3586e3 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -120,18 +120,22 @@ public: return Visit(E->getSubExpr()); } + ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant, + Expr *E) { + assert(Constant && "not a constant"); + if (Constant.isReference()) + return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E), + E->getExprLoc()); + + llvm::Constant *pair = Constant.getValue(); + return ComplexPairTy(pair->getAggregateElement(0U), + pair->getAggregateElement(1U)); + } // l-values. ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { - if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) { - if (result.isReference()) - return EmitLoadOfLValue(result.getReferenceLValue(CGF, E), - E->getExprLoc()); - - llvm::Constant *pair = result.getValue(); - return ComplexPairTy(pair->getAggregateElement(0U), - pair->getAggregateElement(1U)); - } + if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) + return emitConstant(Constant, E); return EmitLoadOfLValue(E); } ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { @@ -141,7 +145,14 @@ public: return CGF.EmitObjCMessageExpr(E).getComplexVal(); } ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } - ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); } + ComplexPairTy VisitMemberExpr(MemberExpr *ME) { + if (CodeGenFunction::ConstantEmission Constant = + CGF.tryEmitAsConstant(ME)) { + CGF.EmitIgnoredExpr(ME->getBase()); + return emitConstant(Constant, ME); + } + return EmitLoadOfLValue(ME); + } ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { if (E->isGLValue()) return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc()); -- cgit v1.2.3