From 59055b94afbfe57a0cdcc230e7d066c275a03619 Mon Sep 17 00:00:00 2001 From: Anastasia Stulova Date: Wed, 9 May 2018 13:23:26 +0000 Subject: [PATCH] [OpenCL] Add constant address space to __func__ in AST. Added string literal helper function to obtain the type attributed by a constant address space. Also fixed predefind __func__ expr to use the helper to constract the string literal correctly. Differential Revision: https://reviews.llvm.org/D46049 llvm-svn: 331877 --- clang/include/clang/AST/ASTContext.h | 2 ++ clang/lib/AST/ASTContext.cpp | 6 ++++++ clang/lib/AST/Expr.cpp | 3 ++- clang/lib/Sema/SemaExpr.cpp | 23 ++++++++++------------- clang/test/CodeGenOpenCL/str_literals.cl | 12 +++++++++--- clang/test/SemaOpenCL/predefined-expr.cl | 8 ++++++++ 6 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 clang/test/SemaOpenCL/predefined-expr.cl diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 0bdb282..dd53c74 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1348,6 +1348,8 @@ public: return getFunctionTypeInternal(ResultTy, Args, EPI, false); } + QualType adjustStringLiteralBaseType(QualType StrLTy) const; + private: /// Return a normal function type with a typed argument list. QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef Args, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0f76136..5c64b94 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3621,6 +3621,12 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const { return QualType(New, 0); } +QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const { + // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. + return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant) + : Ty; +} + QualType ASTContext::getReadPipeType(QualType T) const { return getPipeType(T, true); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index d331c32..f3338dc 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -881,7 +881,8 @@ StringLiteral *StringLiteral::CreateEmpty(const ASTContext &C, void *Mem = C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1), alignof(StringLiteral)); - StringLiteral *SL = new (Mem) StringLiteral(QualType()); + StringLiteral *SL = + new (Mem) StringLiteral(C.adjustStringLiteralBaseType(QualType())); SL->CharByteWidth = 0; SL->Length = 0; SL->NumConcatenated = NumStrs; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ee9e35e..1bec833 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1554,17 +1554,14 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, Scope *UDLScope) { if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) CharTyConst.addConst(); + CharTyConst = Context.adjustStringLiteralBaseType(CharTyConst); + // 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); - } + QualType StrTy = Context.getConstantArrayType( + CharTyConst, llvm::APInt(32, Literal.GetNumStringChars() + 1), + ArrayType::Normal, 0); // Pass &StringTokLocs[0], StringTokLocs.size() to factory! StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), @@ -3046,7 +3043,8 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, llvm::APInt LengthI(32, Length + 1); if (IT == PredefinedExpr::LFunction) { - ResTy = Context.WideCharTy.withConst(); + ResTy = + Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst()); SmallString<32> RawChars; ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(), Str, RawChars); @@ -3055,7 +3053,7 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide, /*Pascal*/ false, ResTy, Loc); } else { - ResTy = Context.CharTy.withConst(); + ResTy = Context.adjustStringLiteralBaseType(Context.CharTy.withConst()); ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, /*IndexTypeQuals*/ 0); SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii, @@ -3294,8 +3292,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // operator "" X ("n") unsigned Length = Literal.getUDSuffixOffset(); QualType StrTy = Context.getConstantArrayType( - Context.CharTy.withConst(), llvm::APInt(32, Length + 1), - ArrayType::Normal, 0); + Context.adjustStringLiteralBaseType(Context.CharTy.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); @@ -13675,7 +13673,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, DiagKind = diag::err_typecheck_incompatible_address_space; break; - } else if (lhq.getObjCLifetime() != rhq.getObjCLifetime()) { DiagKind = diag::err_typecheck_incompatible_ownership; break; diff --git a/clang/test/CodeGenOpenCL/str_literals.cl b/clang/test/CodeGenOpenCL/str_literals.cl index 436af83a..514044c 100644 --- a/clang/test/CodeGenOpenCL/str_literals.cl +++ b/clang/test/CodeGenOpenCL/str_literals.cl @@ -1,9 +1,15 @@ // RUN: %clang_cc1 %s -cl-opt-disable -emit-llvm -o - -ffake-address-space-map | FileCheck %s -__constant char * __constant x = "hello world"; -__constant char * __constant y = "hello world"; +__constant char *__constant x = "hello world"; +__constant char *__constant y = "hello world"; -// CHECK: unnamed_addr addrspace(2) constant +// CHECK: unnamed_addr addrspace(2) constant{{.*}}"hello world\00" // CHECK-NOT: addrspace(2) unnamed_addr constant // CHECK: @x = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)* // CHECK: @y = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)* +// CHECK: unnamed_addr addrspace(2) constant{{.*}}"f\00" + +void f() { + //CHECK: store i8 addrspace(2)* {{.*}}, i8 addrspace(2)** + constant const char *f3 = __func__; +} diff --git a/clang/test/SemaOpenCL/predefined-expr.cl b/clang/test/SemaOpenCL/predefined-expr.cl new file mode 100644 index 0000000..419e7a9 --- /dev/null +++ b/clang/test/SemaOpenCL/predefined-expr.cl @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -verify +// RUN: %clang_cc1 %s -verify -cl-std=CL2.0 + +void f() { + char *f1 = __func__; //expected-error-re{{initializing '{{__generic char|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__; +} -- 2.7.4