From: Enea Zaffanella Date: Mon, 22 Jul 2013 10:58:26 +0000 (+0000) Subject: Implement the part of C89 6.5.7 p3 requiring a constant initializer list X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9a5935c58a3bc78c4a511ee77ad2f0c4ca29dc1;p=clang Implement the part of C89 6.5.7 p3 requiring a constant initializer list when initializing aggregate/union types, no matter if static or not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186817 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1ca349920e..8e88f3d0dd 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3626,6 +3626,8 @@ def warn_typecheck_zero_static_array_size : Warning< def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; +def ext_aggregate_init_not_constant : Extension< + "initializer for aggregate is not a compile-time constant">, InGroup; def err_local_cant_init : Error< "'__local' variable cannot have an initializer">; def err_block_extern_cant_init : Error< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index aeae35aba9..840a735e1b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7777,9 +7777,19 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // C99 6.7.8p4: All the expressions in an initializer for an object that has // static storage duration shall be constant expressions or string literals. // C++ does not have this restriction. - if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() && - VDecl->getStorageClass() == SC_Static) - CheckForConstantInitializer(Init, DclT); + if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) { + if (VDecl->getStorageClass() == SC_Static) + CheckForConstantInitializer(Init, DclT); + // C89 is stricter than C99 for non-static aggregate types. + // C89 6.5.7p3: All the expressions [...] in an initializer list + // for an object that has aggregate or union type shall be + // constant expressions. + else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() && + !Init->isConstantInitializer(Context, false)) + Diag(Init->getExprLoc(), + diag::ext_aggregate_init_not_constant) + << Init->getSourceRange(); + } } else if (VDecl->isStaticDataMember() && VDecl->getLexicalDeclContext()->isRecord()) { // This is an in-class initialization for a static data member, e.g., diff --git a/test/Sema/c89.c b/test/Sema/c89.c index a410a626ed..557acf6d62 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -116,3 +116,7 @@ long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */ 42ULL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */ +void test17(int v, int w) { + int a[2] = { v, w }; /* expected-warning {{initializer for aggregate is not a compile-time constant}} */ +} +