[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