Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -1346,6 +1346,8 @@ return getFunctionTypeInternal(ResultTy, Args, EPI, false); } + QualType getStringLiteralBaseType() const; + private: /// \brief Return a normal function type with a typed argument list. QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef Args, Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -3629,6 +3629,12 @@ return QualType(New, 0); } +QualType ASTContext::getStringLiteralBaseType() const { + // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. + return LangOpts.OpenCL ? getAddrSpaceQualType(CharTy, LangAS::opencl_constant) + : CharTy; +} + QualType ASTContext::getReadPipeType(QualType T) const { return getPipeType(T, true); } Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -881,7 +881,10 @@ void *Mem = C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1), alignof(StringLiteral)); - StringLiteral *SL = new (Mem) StringLiteral(QualType()); + StringLiteral *SL = new (Mem) StringLiteral( + C.getLangOpts().OpenCL + ? C.getAddrSpaceQualType(QualType(), LangAS::opencl_constant) + : QualType()); SL->CharByteWidth = 0; SL->Length = 0; SL->NumConcatenated = NumStrs; Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -1529,7 +1529,7 @@ for (const Token &Tok : StringToks) StringTokLocs.push_back(Tok.getLocation()); - QualType CharTy = Context.CharTy; + QualType CharTy = Context.getStringLiteralBaseType(); StringLiteral::StringKind Kind = StringLiteral::Ascii; if (Literal.isWide()) { CharTy = Context.getWideCharType(); @@ -1554,20 +1554,15 @@ // Get an array type for the string, according to C99 6.4.5. This includes // the nul terminator character as well as the string length for pascal // strings. - QualType StrTy = Context.getConstantArrayType(CharTyConst, - llvm::APInt(32, Literal.GetNumStringChars()+1), - ArrayType::Normal, 0); - - // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. - if (getLangOpts().OpenCL) { - StrTy = Context.getAddrSpaceQualType(StrTy, LangAS::opencl_constant); - } - - // Pass &StringTokLocs[0], StringTokLocs.size() to factory! StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), Kind, Literal.Pascal, StrTy, &StringTokLocs[0], StringTokLocs.size()); + + // Pass &StringTokLocs[0], StringTokLocs.size() to factory! + StringLiteral *Lit = + StringLiteral::Create(Context, Literal.GetString(), Kind, Literal.Pascal, + StrTy, &StringTokLocs[0], StringTokLocs.size()); if (Literal.getUDSuffix().empty()) return Lit; @@ -3051,9 +3046,7 @@ SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide, /*Pascal*/ false, ResTy, Loc); } else { - ResTy = Context.CharTy.withConst(); - if (LangOpts.OpenCL) - ResTy = Context.getAddrSpaceQualType(ResTy, LangAS::opencl_constant); + ResTy = Context.getStringLiteralBaseType().withConst(); ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, /*IndexTypeQuals*/ 0); SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii, @@ -3290,8 +3283,8 @@ // operator "" X ("n") unsigned Length = Literal.getUDSuffixOffset(); QualType StrTy = Context.getConstantArrayType( - Context.CharTy.withConst(), llvm::APInt(32, Length + 1), - ArrayType::Normal, 0); + Context.getStringLiteralBaseType().withConst(), + llvm::APInt(32, Length + 1), ArrayType::Normal, 0); Expr *Lit = StringLiteral::Create( Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii, /*Pascal*/false, StrTy, &TokLoc, 1); @@ -13396,7 +13389,6 @@ DiagKind = diag::err_typecheck_incompatible_address_space; break; - } else if (lhq.getObjCLifetime() != rhq.getObjCLifetime()) { DiagKind = diag::err_typecheck_incompatible_ownership; break; Index: test/SemaOpenCL/predefined-expr.cl =================================================================== --- test/SemaOpenCL/predefined-expr.cl +++ test/SemaOpenCL/predefined-expr.cl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify void f() { -char * f1 = __func__;//expected-error{{initializing 'char *' with an expression of type 'const __constant char *' changes address space of pointer}} -constant char * f2 = __func__;//expected-warning{{initializing '__constant char *' with an expression of type 'const __constant char [2]' discards qualifiers}} -constant const char * f3 = __func__; -} + char *f1 = __func__; //expected-error{{initializing 'char *' with an expression of type 'const __constant char *' changes address space of pointer}} + constant char *f2 = __func__; //expected-warning{{initializing '__constant char *' with an expression of type 'const __constant char [2]' discards qualifiers}} + constant const char *f3 = __func__; +}