From 225d9cf75f9f7af8186e602ba856a9475401619b Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 25 Feb 2014 12:26:20 +0000 Subject: [PATCH] Sema: When merging objc string literals, give the result a constant array type. Also assert that we never create non-array string literals again. PR18939. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202147 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/Expr.cpp | 3 +++ lib/Sema/SemaExprObjC.cpp | 12 ++++++++---- test/SemaObjC/format-strings-objc.m | 3 +++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 3f5833c501..4492d02b7a 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -781,6 +781,9 @@ StringLiteral *StringLiteral::Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs) { + assert(C.getAsConstantArrayType(Ty) && + "StringLiteral must be of constant array type!"); + // Allocate enough space for the StringLiteral plus an array of locations for // any concatenated string tokens. void *Mem = C.Allocate(sizeof(StringLiteral)+ diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 54aa6a610e..3a7e83c5ac 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -67,10 +67,14 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, // Create the aggregate string with the appropriate content and location // information. - S = StringLiteral::Create(Context, StrBuf, - StringLiteral::Ascii, /*Pascal=*/false, - Context.getPointerType(Context.CharTy), - &StrLocs[0], StrLocs.size()); + const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType()); + assert(CAT && "String literal not of constant array type!"); + QualType StrTy = Context.getConstantArrayType( + CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), + CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers()); + S = StringLiteral::Create(Context, StrBuf, StringLiteral::Ascii, + /*Pascal=*/false, StrTy, &StrLocs[0], + StrLocs.size()); } return BuildObjCStringLiteral(AtLocs[0], S); diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m index 2667e3047a..49567a710c 100644 --- a/test/SemaObjC/format-strings-objc.m +++ b/test/SemaObjC/format-strings-objc.m @@ -116,6 +116,9 @@ NSString *test_literal_propagation(void) { NSLog(ns2); // expected-warning {{more '%' conversions than data arguments}} NSString * ns3 = ns1; NSLog(ns3); // expected-warning {{format string is not a string literal}}} + + NSString * const ns6 = @"split" " string " @"%s"; // expected-note {{format string is defined here}} + NSLog(ns6); // expected-warning {{more '%' conversions than data arguments}} } // Do not emit warnings when using NSLocalizedString -- 2.40.0