[cfe-commits] r57313 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Wed Oct 8 15:20:31 PDT 2008


Author: akirtzidis
Date: Wed Oct  8 17:20:31 2008
New Revision: 57313

URL: http://llvm.org/viewvc/llvm-project?rev=57313&view=rev
Log:
Fix a bug that crashed clang when parsing this:

class C {
  static const int number = 50;
  static int arr[number];
};

Here's how it worked:
-GetTypeForDeclarator was called from both Sema::ActOnCXXMemberDeclarator and Sema::ActOnDeclarator.
-VariableArrayTypes are not uniqued so two VariableArrayTypes were created with the same DeclRefExpr.
-On exit they both tried to destroy that one DeclRefExpr.

The fix is not to use GetTypeForDeclarator from the Sema::ActOnCXXMemberDeclarator.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/class.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=57313&r1=57312&r2=57313&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Oct  8 17:20:31 2008
@@ -352,15 +352,19 @@
       D.getMutableDeclSpec().ClearStorageClassSpecs();
   }
 
-  QualType T = GetTypeForDeclarator(D, S);
+  bool isFunc = D.isFunctionDeclarator();
+  if (!isFunc && D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typedef) {
+    // Check also for this case:
+    //
+    // typedef int f();
+    // f a;
+    //
+    Decl *TD = static_cast<Decl *>(DS.getTypeRep());
+    isFunc = Context.getTypeDeclType(cast<TypeDecl>(TD))->isFunctionType();
+  }
 
-  // T->isFunctionType() is used instead of D.isFunctionDeclarator() to cover
-  // this case:
-  //
-  // typedef int f();
-  // f a;
   bool isInstField = (DS.getStorageClassSpec() == DeclSpec::SCS_unspecified &&
-                      !T->isFunctionType());
+                      !isFunc);
 
   Decl *Member;
   bool InvalidDecl = false;
@@ -391,15 +395,21 @@
            II->getName(), BitWidth->getSourceRange());
       InvalidDecl = true;
 
-    } else if (isInstField || isa<FunctionDecl>(Member)) {
-      // An instance field or a function typedef ("typedef int f(); f a;").
+    } else if (isInstField) {
       // C++ 9.6p3: A bit-field shall have integral or enumeration type.
-      if (!T->isIntegralType()) {
+      if (!cast<FieldDecl>(Member)->getType()->isIntegralType()) {
         Diag(Loc, diag::err_not_integral_type_bitfield,
              II->getName(), BitWidth->getSourceRange());
         InvalidDecl = true;
       }
 
+    } else if (isa<FunctionDecl>(Member)) {
+      // A function typedef ("typedef int f(); f a;").
+      // C++ 9.6p3: A bit-field shall have integral or enumeration type.
+      Diag(Loc, diag::err_not_integral_type_bitfield,
+           II->getName(), BitWidth->getSourceRange());
+      InvalidDecl = true;
+
     } else if (isa<TypedefDecl>(Member)) {
       // "cannot declare 'A' to be a bit-field type"
       Diag(Loc, diag::err_not_bitfield_type, II->getName(), 

Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=57313&r1=57312&r2=57313&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Wed Oct  8 17:20:31 2008
@@ -55,6 +55,9 @@
 private:
   int x,y;
   static int sx;
+
+  static const int number = 50;
+  static int arr[number];
 };
 
 class C2 {





More information about the cfe-commits mailing list