diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index b81f3fe53e..c6f1203e68 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -526,6 +526,11 @@ bool Sema::CheckInitializerListTypes(InitListExpr*& IList, QualType &DeclType, ++startIndex; } else { RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl(); + + // If the record is invalid, it's members can't be trusted. + if (structDecl->isInvalidDecl()) + return true; + // If structDecl is a forward declaration, this loop won't do anything; // That's okay, because an error should get printed out elsewhere. It // might be worthwhile to skip over the rest of the initializer, though. diff --git a/test/Sema/invalid-struct-init.c b/test/Sema/invalid-struct-init.c new file mode 100644 index 0000000000..1cfc0c4b21 --- /dev/null +++ b/test/Sema/invalid-struct-init.c @@ -0,0 +1,27 @@ +// RUN: clang %s -verify -fsyntax-only + +typedef struct _zend_module_entry zend_module_entry; +struct _zend_module_entry { + _efree((p)); // expected-error{{type name requires a specifier or qualifier}} \ + // expected-error{{type specifier required for parameter 'p'}} \ + // expected-error{{field '_efree' declared as a function}} +}; +typedef struct _zend_function_entry { } zend_function_entry; +typedef struct _zend_pcre_globals { } zend_pcre_globals; +zend_pcre_globals pcre_globals; + +static void zm_globals_ctor_pcre(zend_pcre_globals *pcre_globals ) { } +static void zm_globals_dtor_pcre(zend_pcre_globals *pcre_globals ) { } +static void zm_info_pcre(zend_module_entry *zend_module ) { } +static int zm_startup_pcre(int type, int module_number ) { } + +static int zm_shutdown_pcre(int type, int module_number ) { + zend_function_entry pcre_functions[] = {{ }; // expected-error{{expected '}'}} expected-error{{to match this '{'}} + zend_module_entry pcre_module_entry = { + sizeof(zend_module_entry), 20071006, 0, 0, ((void *)0), ((void *)0), + "pcre", pcre_functions, zm_startup_pcre, zm_shutdown_pcre, ((void *)0), + ((void *)0), zm_info_pcre, ((void *)0), sizeof(zend_pcre_globals), &pcre_globals, + ((void (*)(void* ))(zm_globals_ctor_pcre)), ((void (*)(void* ))(zm_globals_dtor_pcre)), + ((void *)0), 0, 0, ((void *)0), 0 + }; +}