]> granicus.if.org Git - clang/commitdiff
Fix a bug that crashed clang when parsing this:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 8 Oct 2008 22:20:31 +0000 (22:20 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 8 Oct 2008 22:20:31 +0000 (22:20 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57313 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/class.cpp

index 4d8c16bf53e526ec952419b60e7c6695dc4c8a70..2fae627ea6ac9dc9b23917584901148661c3de46 100644 (file)
@@ -352,15 +352,19 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
       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 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
            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(), 
index 1fbff69cb5879445f78760ce4957c9a7285b2003..71ad7de91436ee15caed523799e3ad2de8108cf3 100644 (file)
@@ -55,6 +55,9 @@ public:
 private:
   int x,y;
   static int sx;
+
+  static const int number = 50;
+  static int arr[number];
 };
 
 class C2 {