[cfe-dev] [PATCH] Flexible array initializers may be strings
Pierre Habouzit
madcoder at madism.org
Fri Sep 24 02:14:12 PDT 2010
for example:
struct a {
int b;
char v[];
};
struct a foo = { .b = 0, .v = "bar" };
is perfectly sensible and correct (and accepted by gcc).
Signed-off-by: Pierre Habouzit <madcoder at debian.org>
---
lib/Sema/SemaInit.cpp | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
For the record, clang accepts the following code:
-------8<-----------
#include <stdio.h>
struct a {
int i;
char v[];
};
int main(void) {
struct a foo = { .i = 0, .v = "foo" };
struct a bar = { .i = 0, .v = { 'b', 'a', 'r', '\0' } };
printf("%p %s\n", foo.v, foo.v);
printf("%p %s\n", bar.v, bar.v);
return 0;
}
-------8<-----------
whereas gcc rejects it with the error:
error: non-static initialization of a flexible array member
Clang doesn't complain, but generates invalid code though when foo and bar
aren't static:
$ clang -o a a.c && ./a
0x7fff1eccc32c
0x7fff1eccc324 ΓΏ
Reading the relevant parts of the bitcode indeed shows what is wrong:
there is a correct internal constant for main.foo, but the variable
foo storage is allocated using sizeof(struct a) instead of
sizeof(main.foo), and the memcpy also uses sizeof(struct a) which is
4 instead of sizeof(main.foo).
@main.foo = internal constant %0 { i32 0, [4 x i8] c"foo\00" }, align 4
%foo = alloca %struct.a, align 4
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* bitcast (%0* @main.foo to i8*), i64 4, i32 4, i1 false)
Sadly fixing that exceeds my current clang hacking skills. Do you
want me to report a bug for that ?
declare i32 @printf(i8*, ...)
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 1ffa702..916134e 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1461,7 +1461,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
Invalid = true;
}
- if (!hadError && !isa<InitListExpr>(DIE->getInit())) {
+ if (!hadError && !isa<InitListExpr>(DIE->getInit()) && !isa<StringLiteral>(DIE->getInit())) {
// The initializer is not an initializer list.
SemaRef.Diag(DIE->getInit()->getSourceRange().getBegin(),
diag::err_flexible_array_init_needs_braces)
--
1.7.2.2.566.g36af9
More information about the cfe-dev
mailing list