diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-08 22:20:31 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-08 22:20:31 +0000 |
commit | de933f025e839bde4b119f3437c320c2137bbe1f (patch) | |
tree | 3a84603092a448a9b7c40d5a265c15b3d8e7aa44 | |
parent | 1c90bfcbd7ff5d09694acf50a32dbb716a968b61 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57313 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 30 | ||||
-rw-r--r-- | test/SemaCXX/class.cpp | 3 |
2 files changed, 23 insertions, 10 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4d8c16bf53..2fae627ea6 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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(), diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index 1fbff69cb5..71ad7de914 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -55,6 +55,9 @@ public: private: int x,y; static int sx; + + static const int number = 50; + static int arr[number]; }; class C2 { |