[cfe-commits] r116166 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/Sema/flexible-array-init.c test/Sema/init.c

Chris Lattner sabre at nondot.org
Sun Oct 10 11:16:20 PDT 2010


Author: lattner
Date: Sun Oct 10 13:16:20 2010
New Revision: 116166

URL: http://llvm.org/viewvc/llvm-project?rev=116166&view=rev
Log:
fix PR8217, a silent miscompilation of invalid code.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/flexible-array-init.c
    cfe/trunk/test/Sema/init.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=116166&r1=116165&r2=116166&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun Oct 10 13:16:20 2010
@@ -2876,12 +2876,12 @@
 
   unsigned getNumInits() const { return InitExprs.size(); }
 
-  const Expr* getInit(unsigned Init) const {
+  const Expr *getInit(unsigned Init) const {
     assert(Init < getNumInits() && "Initializer access out of range!");
     return cast_or_null<Expr>(InitExprs[Init]);
   }
 
-  Expr* getInit(unsigned Init) {
+  Expr *getInit(unsigned Init) {
     assert(Init < getNumInits() && "Initializer access out of range!");
     return cast_or_null<Expr>(InitExprs[Init]);
   }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=116166&r1=116165&r2=116166&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Oct 10 13:16:20 2010
@@ -2152,6 +2152,8 @@
   "out-of-line definition of %0 does not match any declaration in %1">;
 def err_nonstatic_member_out_of_line : Error<
   "non-static data member defined out-of-line">;
+def err_nonstatic_flexible_variable : Error<
+  "non-static initialization of a variable with flexible array member">;
 def err_qualified_typedef_declarator : Error<
   "typedef declarator cannot be qualified">;
 def err_qualified_param_declarator : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=116166&r1=116165&r2=116166&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Oct 10 13:16:20 2010
@@ -1591,7 +1591,6 @@
 /// no declarator (e.g. "struct foo;") is parsed.
 Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
                                             DeclSpec &DS) {
-  // FIXME: Error on auto/register at file scope
   // FIXME: Error on inline/virtual/explicit
   // FIXME: Warn on useless __thread
   // FIXME: Warn on useless const/volatile
@@ -2686,7 +2685,7 @@
 }
 
 NamedDecl*
-Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               QualType R, TypeSourceInfo *TInfo,
                               LookupResult &Previous,
                               MultiTemplateParamsArg TemplateParamLists,
@@ -2821,7 +2820,7 @@
   ProcessDeclAttributes(S, NewVD, D);
 
   // Handle GNU asm-label extension (encoded as an attribute).
-  if (Expr *E = (Expr*) D.getAsmLabel()) {
+  if (Expr *E = (Expr*)D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), 
@@ -2991,7 +2990,7 @@
   // This includes arrays of objects with address space qualifiers, but not
   // automatic variables that point to other address spaces.
   // ISO/IEC TR 18037 S5.1.2
-  if (NewVD->hasLocalStorage() && (T.getAddressSpace() != 0)) {
+  if (NewVD->hasLocalStorage() && T.getAddressSpace() != 0) {
     Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
     return NewVD->setInvalidDecl();
   }
@@ -2999,7 +2998,7 @@
   if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
       && !NewVD->hasAttr<BlocksAttr>())
     Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
-
+  
   bool isVM = T->isVariablyModifiedType();
   if (isVM || NewVD->hasAttr<CleanupAttr>() ||
       NewVD->hasAttr<BlocksAttr>())
@@ -4326,6 +4325,17 @@
     Init->setType(DclT);
   }
 
+  
+  // If this variable is a local declaration with record type, make sure it
+  // doesn't have a flexible member initialization.  We only support this as a
+  // global/static definition.
+  if (VDecl->hasLocalStorage())
+    if (const RecordType *RT = VDecl->getType()->getAs<RecordType>())
+      if (RT->getDecl()->hasFlexibleArrayMember() && isa<InitListExpr>(Init)) {
+        Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
+        VDecl->setInvalidDecl();
+      }
+  
   // Check any implicit conversions within the expression.
   CheckImplicitConversions(Init, VDecl->getLocation());
 

Modified: cfe/trunk/test/Sema/flexible-array-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/flexible-array-init.c?rev=116166&r1=116165&r2=116166&view=diff
==============================================================================
--- cfe/trunk/test/Sema/flexible-array-init.c (original)
+++ cfe/trunk/test/Sema/flexible-array-init.c Sun Oct 10 13:16:20 2010
@@ -7,7 +7,9 @@
 struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}}
 
 void test() {
-  struct one x3 = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
+  struct one x3 = {5, {1, 2, 3}}; // \
+   // expected-warning{{flexible array initialization is a GNU extension}} \
+   // expected-error {{non-static initialization of a variable with flexible array member}}
 }
 
 struct foo { 
@@ -56,3 +58,18 @@
   int e;
   struct X xs[]; // expected-warning{{'struct X' may not be used as an array element due to flexible array member}}
 };
+
+
+// PR8217
+struct PR8217a {
+  int  i;
+  char v[];
+};
+
+void PR8217() {
+  struct PR8217a foo1 = { .i = 0, .v = "foo" }; // expected-error {{non-static initialization of a variable with flexible array member}}
+  struct PR8217a foo2 = { .i = 0 }; // expected-error {{non-static initialization of a variable with flexible array member}}
+  struct PR8217a foo3 = { .i = 0, .v = { 'b', 'a', 'r', '\0' } }; // expected-error {{non-static initialization of a variable with flexible array member}}
+  struct PR8217a bar;
+}
+

Modified: cfe/trunk/test/Sema/init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/init.c?rev=116166&r1=116165&r2=116166&view=diff
==============================================================================
--- cfe/trunk/test/Sema/init.c (original)
+++ cfe/trunk/test/Sema/init.c Sun Oct 10 13:16:20 2010
@@ -143,3 +143,4 @@
 int PR4386_b = ((void *) PR4386_foo) != 0; // expected-error{{initializer element is not a compile-time constant}}
 int PR4386_c = ((void *) PR4386_zed) != 0;
 int PR4386_zed() __attribute((weak));
+





More information about the cfe-commits mailing list