[cfe-commits] r46984 - in /cfe/trunk: Parse/DeclSpec.cpp Parse/Parser.cpp include/clang/Parse/DeclSpec.h test/Sema/declspec.c
Steve Naroff
snaroff at apple.com
Mon Feb 11 20:09:00 PST 2008
Author: snaroff
Date: Mon Feb 11 22:08:59 2008
New Revision: 46984
URL: http://llvm.org/viewvc/llvm-project?rev=46984&view=rev
Log:
Allow the parser to detect invalid DeclSpec's. This fixes http://llvm.org/bugs/show_bug.cgi?id=1987.
This commit only "guards" the call to ParseDeclarationSpecifiers() in ParseDeclarationOrFunctionDefinition().
We could consider guarding all calls, however this is a bit radical (since it effectively stops parsing the declaration once we have a bad declspec). Will discuss with Chris tomorrow.
Modified:
cfe/trunk/Parse/DeclSpec.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/include/clang/Parse/DeclSpec.h
cfe/trunk/test/Sema/declspec.c
Modified: cfe/trunk/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/DeclSpec.cpp?rev=46984&r1=46983&r2=46984&view=diff
==============================================================================
--- cfe/trunk/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/Parse/DeclSpec.cpp Mon Feb 11 22:08:59 2008
@@ -47,36 +47,40 @@
}
}
-static bool BadSpecifier(DeclSpec::SCS S, const char *&PrevSpec) {
- PrevSpec = DeclSpec::getSpecifierName(S);
+bool DeclSpec::BadSpecifier(SCS S, const char *&PrevSpec) {
+ Invalid = true;
+ PrevSpec = getSpecifierName(S);
return true;
}
-static bool BadSpecifier(DeclSpec::TSW W, const char *&PrevSpec) {
+bool DeclSpec::BadSpecifier(TSW W, const char *&PrevSpec) {
+ Invalid = true;
switch (W) {
- case DeclSpec::TSW_unspecified: PrevSpec = "unspecified"; break;
- case DeclSpec::TSW_short: PrevSpec = "short"; break;
- case DeclSpec::TSW_long: PrevSpec = "long"; break;
- case DeclSpec::TSW_longlong: PrevSpec = "long long"; break;
+ case TSW_unspecified: PrevSpec = "unspecified"; break;
+ case TSW_short: PrevSpec = "short"; break;
+ case TSW_long: PrevSpec = "long"; break;
+ case TSW_longlong: PrevSpec = "long long"; break;
}
return true;
}
-static bool BadSpecifier(DeclSpec::TSC C, const char *&PrevSpec) {
+bool DeclSpec::BadSpecifier(TSC C, const char *&PrevSpec) {
+ Invalid = true;
switch (C) {
- case DeclSpec::TSC_unspecified: PrevSpec = "unspecified"; break;
- case DeclSpec::TSC_imaginary: PrevSpec = "imaginary"; break;
- case DeclSpec::TSC_complex: PrevSpec = "complex"; break;
+ case TSC_unspecified: PrevSpec = "unspecified"; break;
+ case TSC_imaginary: PrevSpec = "imaginary"; break;
+ case TSC_complex: PrevSpec = "complex"; break;
}
return true;
}
-static bool BadSpecifier(DeclSpec::TSS S, const char *&PrevSpec) {
+bool DeclSpec::BadSpecifier(TSS S, const char *&PrevSpec) {
+ Invalid = true;
switch (S) {
- case DeclSpec::TSS_unspecified: PrevSpec = "unspecified"; break;
- case DeclSpec::TSS_signed: PrevSpec = "signed"; break;
- case DeclSpec::TSS_unsigned: PrevSpec = "unsigned"; break;
+ case TSS_unspecified: PrevSpec = "unspecified"; break;
+ case TSS_signed: PrevSpec = "signed"; break;
+ case TSS_unsigned: PrevSpec = "unsigned"; break;
}
return true;
}
@@ -103,12 +107,14 @@
}
}
-static bool BadSpecifier(DeclSpec::TST T, const char *&PrevSpec) {
- PrevSpec = DeclSpec::getSpecifierName(T);
+bool DeclSpec::BadSpecifier(TST T, const char *&PrevSpec) {
+ Invalid = true;
+ PrevSpec = getSpecifierName(T);
return true;
}
-static bool BadSpecifier(DeclSpec::TQ T, const char *&PrevSpec) {
+bool DeclSpec::BadSpecifier(TQ T, const char *&PrevSpec) {
+ Invalid = true;
switch (T) {
case DeclSpec::TQ_unspecified: PrevSpec = "unspecified"; break;
case DeclSpec::TQ_const: PrevSpec = "const"; break;
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=46984&r1=46983&r2=46984&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Mon Feb 11 22:08:59 2008
@@ -367,7 +367,10 @@
// Parse the common declaration-specifiers piece.
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
-
+ // If the decl specs are invalid, there is no need to continue.
+ if (DS.isInvalid())
+ return 0;
+
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
// declaration-specifiers init-declarator-list[opt] ';'
if (Tok.is(tok::semi)) {
Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=46984&r1=46983&r2=46984&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Feb 11 22:08:59 2008
@@ -134,6 +134,15 @@
SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
SourceLocation FS_inlineLoc;
+
+ bool Invalid;
+
+ bool BadSpecifier(TST T, const char *&PrevSpec);
+ bool BadSpecifier(TQ T, const char *&PrevSpec);
+ bool BadSpecifier(TSS T, const char *&PrevSpec);
+ bool BadSpecifier(TSC T, const char *&PrevSpec);
+ bool BadSpecifier(TSW T, const char *&PrevSpec);
+ bool BadSpecifier(SCS T, const char *&PrevSpec);
public:
DeclSpec()
@@ -147,7 +156,8 @@
FS_inline_specified(false),
TypeRep(0),
AttrList(0),
- ProtocolQualifiers(0) {
+ ProtocolQualifiers(0),
+ Invalid(false) {
}
~DeclSpec() {
delete AttrList;
@@ -160,6 +170,7 @@
SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+ bool isInvalid() { return Invalid; }
void ClearStorageClassSpecs() {
StorageClassSpec = DeclSpec::SCS_unspecified;
Modified: cfe/trunk/test/Sema/declspec.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/declspec.c?rev=46984&r1=46983&r2=46984&view=diff
==============================================================================
--- cfe/trunk/test/Sema/declspec.c (original)
+++ cfe/trunk/test/Sema/declspec.c Mon Feb 11 22:08:59 2008
@@ -5,4 +5,8 @@
void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void);
-
+struct _zend_module_entry { }
+typedef struct _zend_function_entry { } // expected-error {{cannot combine with previous 'struct' declaration specifier}}
+static void buggy(int *x) { // expected-error {{cannot combine with previous 'typedef' declaration specifier}} \
+ // expected-error {{cannot combine with previous 'struct' declaration specifier}}
+ // expected-error {{expected '}'}}
More information about the cfe-commits
mailing list