]> granicus.if.org Git - clang/commitdiff
Handle ObjCEncodeExpr in extractStringLiteralCharacter.
authorAkira Hatanaka <ahatanaka@apple.com>
Tue, 31 Jan 2017 02:31:39 +0000 (02:31 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Tue, 31 Jan 2017 02:31:39 +0000 (02:31 +0000)
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/trunk@293596 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/CodeGenObjC/encode-test.m

index de0535463808391b8cd682b4970e89a02c3ad5f2..3b6e3ab5e5e6a18c0802fcc0e5257ed2c09e74a5 100644 (file)
@@ -2394,7 +2394,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);
index 7f0e76fc3ffd4deb1d9b52c923a6582e848b2d56..a1f88e05250a9488629a83415e8d635edc7318f9 100644 (file)
@@ -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);
+}