multi-dimensional char arrays

The following source fails to parse:

$ cat a.c
const char w[4] = “ab”;
const char x[2][4] = { { ‘a’, ‘b’, ‘\0’, ‘\0’ }, { ‘c’, ‘d’, ‘e’, ‘\0’ } };
const char y[2][4] = { “ab”, “cde” };
const char y2[2][4] = { { “ab” }, { “cde” } };
const char * const z[2] = { “ab”, “cde” };
]$ clang -std=c99 a.c -fsyntax-only
a.c:3:30: error: excess elements in char array initializer
const char y[2][4] = { “ab”, “cde” };
^~~~~
1 diagnostic generated.
$

This appears to be C99 6.7.8.14:

14 An array of character type may be initialized by a character string literal, optionally
enclosed in braces. Successive characters of the character string literal (including the
terminating null character if there is room or if the array is of unknown size) initialize the
elements of the array.

Additionally, even when compiling just “x”, -emit-llvm fails:

$ cat b.c
const char x[2][4] = { { ‘a’, ‘b’, ‘\0’, ‘\0’ }, { ‘c’, ‘d’, ‘e’, ‘\0’ } };
$ clang -std=c99 b.c -ast-dump
typedef char __builtin_va_list;
Read top-level variable decl: ‘x’
$ clang -std=c99 b.c -emit-llvm 2>&1 | c++filt -n
Assertion failed: (ILE->getType()->isArrayType() || ILE->getType()->isStructureType()), function GenerateAggregateInit, file CodeGenModule.cpp, line 284.
0 clang 0x0021b8cb (anonymous namespace)::PrintStackTrace() + 45
1 clang 0x0021bc71 (anonymous namespace)::SignalHandler(int) + 323
2 libSystem.B.dylib 0x9188897b _sigtramp + 43
3 ??? 0xffffffff 0x0 + 4294967295
4 libSystem.B.dylib 0x91901782 raise + 26
5 libSystem.B.dylib 0x91910d3f abort + 73
6 libSystem.B.dylib 0x91902923 __assert_rtn + 101
7 clang 0x0005d9a1 clang::CodeGen::CodeGenModule::GetAddrOfConstantCFString(std::basic_string<char, std::char_traits, std::allocator > const&) + 1577
8 clang 0x0005e4ce clang::CodeGen::CodeGenModule::GetAddrOfConstantCFString(std::basic_string<char, std::char_traits, std::allocator > const&) + 4438
9 clang 0x0005dae3 clang::CodeGen::CodeGenModule::GetAddrOfConstantCFString(std::basic_string<char, std::char_traits, std::allocator > const&) + 1899
10 clang 0x0005e4ce clang::CodeGen::CodeGenModule::GetAddrOfConstantCFString(std::basic_string<char, std::char_traits, std::allocator > const&) + 4438
11 clang 0x0005e53e clang::CodeGen::CodeGenModule::EmitGlobalInit(clang::Expr const
) + 24
12 clang 0x0005e6d6 clang::CodeGen::CodeGenModule::EmitGlobalVar(clang::FileVarDecl const*) + 406
13 clang 0x0005e7e6 clang::CodeGen::CodeGenModule::EmitGlobalVarDeclarator(clang::FileVarDecl const*) + 26
14 clang 0x00067ddc clang::CodeGen::CodeGenGlobalVar(clang::CodeGen::CodeGenModule*, clang::FileVarDecl*) + 24
15 clang 0x00006229 (anonymous namespace)::LLVMEmitter::HandleTopLevelDecl(clang::Decl*) + 119
16 clang 0x0007af58 clang::ParseAST(clang::Preprocessor&, unsigned int, clang::ASTConsumer*, bool) + 258
17 clang 0x000222c2 llvm::BitstreamWriter::Emit(unsigned int, unsigned int) + 3740
18 clang 0x0002444e main + 1370
19 clang 0x00001cca start + 54

Shantonu Sen
ssen@apple.com

Shantonu,

Thanks for the bug report.

fyi…clang’s initializer support is still incomplete (e.g. we still don’t support structures). Back in September, I added some basic support that implements ~85% of the C99 spec. Since then, Anders and I made some tweaks for supporting “basic” character arrays (which doesn’t correctly handle the case below).

I hope to finish initializer support after the holidays.

snaroff

fyi…clang’s initializer support is still incomplete (e.g. we still don’t support structures). Back in September, I added some basic support that implements ~85% of the C99 spec. Since then, Anders and I made some tweaks for supporting “basic” character arrays (which doesn’t correctly handle the case below).

I hope to finish initializer support after the holidays.

In the meantime, enough people are hitting the codegen assertion that I added a hack to the code generator to warn about it and carry on. You’ll get invalid code, but at least you won’t get crashes all over the place:

t3.c:1:24: warning: cannot codegen this initializer yet
const char x[2][4] = { { ‘a’, ‘b’, ‘\0’, ‘\0’ }, { ‘c’, ‘d’, ‘e’, ‘\0’ } };
^~~~~~~~~~~~~~~~~~~~~~~~

-Chris