From 1b8468f0151f4ed390f7b8e139fc502425d086f7 Mon Sep 17 00:00:00 2001 From: Hans Wennborg <hans@hanshq.net> Date: Tue, 31 Jan 2017 17:27:07 +0000 Subject: [PATCH] Merging r293596: ------------------------------------------------------------------------ r293596 | ahatanak | 2017-01-30 18:31:39 -0800 (Mon, 30 Jan 2017) | 7 lines Handle ObjCEncodeExpr in extractStringLiteralCharacter. This fixes an assertion failure that occurs later in the function when an ObjCEncodeExpr is cast to StringLiteral. rdar://problem/30111207 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_40@293653 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 9 ++++++++- test/CodeGenObjC/encode-test.m | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 5fab58a5af9..6a6baf96ad3 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2362,7 +2362,14 @@ static unsigned getBaseIndex(const CXXRecordDecl *Derived, /// Extract the value of a character from a string literal. static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index) { - // FIXME: Support ObjCEncodeExpr, MakeStringConstant + // FIXME: Support MakeStringConstant + if (const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) { + std::string Str; + Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str); + assert(Index <= Str.size() && "Index too large"); + return APSInt::getUnsigned(Str.c_str()[Index]); + } + if (auto PE = dyn_cast<PredefinedExpr>(Lit)) Lit = PE->getFunctionName(); const StringLiteral *S = cast<StringLiteral>(Lit); diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m index 7f0e76fc3ff..a1f88e05250 100644 --- a/test/CodeGenObjC/encode-test.m +++ b/test/CodeGenObjC/encode-test.m @@ -180,3 +180,14 @@ const char g14[] = @encode(__typeof__(*test_id)); // CHECK: @g15 = constant [2 x i8] c":\00" const char g15[] = @encode(SEL); + +typedef typeof(sizeof(int)) size_t; +size_t strlen(const char *s); + +// CHECK-LABEL: @test_strlen( +// CHECK: %[[i:.*]] = alloca i32 +// CHECK: store i32 1, i32* %[[i]] +void test_strlen() { + const char array[] = @encode(int); + int i = strlen(array); +} -- GitLab