mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-25 10:48:14 +00:00
Handle parens properly when initializing a char array from a string literal.
llvm-svn: 181159
This commit is contained in:
parent
e54c307bb4
commit
430c23bb42
@ -82,6 +82,17 @@ static Expr *IsStringInit(Expr *init, QualType declType, ASTContext &Context) {
|
||||
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, QualType &DeclT, const ArrayType *AT,
|
||||
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, QualType &DeclT, const ArrayType *AT,
|
||||
// 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, QualType &DeclT, const ArrayType *AT,
|
||||
// something like:
|
||||
// char x[1] = "foo";
|
||||
// then this will set the string literal's type to char[1].
|
||||
Str->setType(DeclT);
|
||||
updateStringLiteralType(Str, DeclT);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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 {
|
||||
|
@ -4,3 +4,5 @@ const wchar_t *pascalString = L"\pThis is a Pascal string";
|
||||
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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user