r181159 - Handle parens properly when initializing a char array from a string literal.
Richard Smith
richard-llvm at metafoo.co.uk
Sun May 5 09:40:13 PDT 2013
Author: rsmith
Date: Sun May 5 11:40:13 2013
New Revision: 181159
URL: http://llvm.org/viewvc/llvm-project?rev=181159&view=rev
Log:
Handle parens properly when initializing a char array from a string literal.
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
cfe/trunk/test/SemaCXX/pascal-strings.cpp
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=181159&r1=181158&r2=181159&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun May 5 11:40:13 2013
@@ -82,6 +82,17 @@ static Expr *IsStringInit(Expr *init, Qu
return IsStringInit(init, arrayType, Context);
}
+/// Update the type of a string literal, including any surrounding parentheses,
+/// to match the type of the object which it is initializing.
+static void updateStringLiteralType(Expr *E, QualType Ty) {
+ while (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+ E->setType(Ty);
+ E = PE->getSubExpr();
+ }
+ assert(isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E));
+ E->setType(Ty);
+}
+
static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
Sema &S) {
// Get the length of the string as parsed.
@@ -97,7 +108,7 @@ static void CheckStringInit(Expr *Str, Q
DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
ConstVal,
ArrayType::Normal, 0);
- Str->setType(DeclT);
+ updateStringLiteralType(Str, DeclT);
return;
}
@@ -107,7 +118,7 @@ static void CheckStringInit(Expr *Str, Q
// the size may be smaller or larger than the string we are initializing.
// FIXME: Avoid truncation for 64-bit length strings.
if (S.getLangOpts().CPlusPlus) {
- if (StringLiteral *SL = dyn_cast<StringLiteral>(Str)) {
+ if (StringLiteral *SL = dyn_cast<StringLiteral>(Str->IgnoreParens())) {
// For Pascal strings it's OK to strip off the terminating null character,
// so the example below is valid:
//
@@ -133,7 +144,7 @@ static void CheckStringInit(Expr *Str, Q
// something like:
// char x[1] = "foo";
// then this will set the string literal's type to char[1].
- Str->setType(DeclT);
+ updateStringLiteralType(Str, DeclT);
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=181159&r1=181158&r2=181159&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sun May 5 11:40:13 2013
@@ -414,6 +414,19 @@ struct V {
};
static_assert(V().c[1] == "i"[0], "");
+namespace Parens {
+ constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")},
+ d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")};
+ static_assert(a[0] == 'f', "");
+ static_assert(b[1] == 'o', "");
+ static_assert(c[2] == 'o', "");
+ static_assert(d[0] == 'f', "");
+ static_assert(e[1] == 'o', "");
+ static_assert(f[2] == 'o', "");
+ static_assert(f[5] == 0, "");
+ static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+}
+
}
namespace Array {
Modified: cfe/trunk/test/SemaCXX/pascal-strings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pascal-strings.cpp?rev=181159&r1=181158&r2=181159&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pascal-strings.cpp (original)
+++ cfe/trunk/test/SemaCXX/pascal-strings.cpp Sun May 5 11:40:13 2013
@@ -4,3 +4,5 @@ const wchar_t *pascalString = L"\pThis i
unsigned char a[3] = "\pa";
unsigned char b[3] = "\pab";
unsigned char c[3] = "\pabc"; // expected-error {{initializer-string for char array is too long}}
+unsigned char d[3] = ("\pab");
+unsigned char e[3] = ("\pabc"); // expected-error {{initializer-string for char array is too long}}
More information about the cfe-commits
mailing list