aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-08 22:20:31 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-08 22:20:31 +0000
commitde933f025e839bde4b119f3437c320c2137bbe1f (patch)
tree3a84603092a448a9b7c40d5a265c15b3d8e7aa44
parent1c90bfcbd7ff5d09694acf50a32dbb716a968b61 (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.cpp30
-rw-r--r--test/SemaCXX/class.cpp3
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 {