[cfe-commits] r61454 - in /cfe/trunk: include/clang/Parse/DeclSpec.h lib/Parse/DeclSpec.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp test/Parser/cxx-template-decl.cpp test/Sema/decl-invalid.c test/SemaCXX/class.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Sun Dec 28 07:29:01 PST 2008


Author: cornedbee
Date: Sun Dec 28 09:28:59 2008
New Revision: 61454

URL: http://llvm.org/viewvc/llvm-project?rev=61454&view=rev
Log:
Diagnose declarations that don't declare anything, and fix PR3020.
Examples:
int;
typedef int;

Modified:
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/Parse/DeclSpec.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp
    cfe/trunk/test/Sema/decl-invalid.c
    cfe/trunk/test/SemaCXX/class.cpp

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Sun Dec 28 09:28:59 2008
@@ -318,6 +318,10 @@
   /// things like "_Imaginary" (lacking an FP type).  After calling this method,
   /// DeclSpec is guaranteed self-consistent, even if an error occurred.
   void Finish(Diagnostic &D, SourceManager& SrcMgr, const LangOptions &Lang);
+
+  /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone,
+  /// without a Declarator. Only tag declspecs can stand alone.
+  bool isMissingDeclaratorOk();
 };
 
 /// ObjCDeclSpec - This class captures information about 

Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Sun Dec 28 09:28:59 2008
@@ -313,3 +313,11 @@
   // 'data definition has no type or storage class'?
 }
 
+bool DeclSpec::isMissingDeclaratorOk() {
+  TST tst = getTypeSpecType();
+  return (tst == TST_union
+       || tst == TST_struct
+       || tst == TST_class
+       || tst == TST_enum
+      ) && getTypeRep() != 0;
+}

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Dec 28 09:28:59 2008
@@ -302,7 +302,7 @@
 
   /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
   /// no declarator (e.g. "struct foo;") is parsed.
-  virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);  
+  virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
   
   virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
                            SourceLocation KWLoc, const CXXScopeSpec &SS,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Dec 28 09:28:59 2008
@@ -773,10 +773,17 @@
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
 /// no declarator (e.g. "struct foo;") is parsed.
 Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
-  // TODO: emit error on 'int;' or 'const enum foo;'.
-  // TODO: emit error on 'typedef int;'
-  // if (!DS.isMissingDeclaratorOk()) Diag(...);
-  
+  // FIXME: Isn't that more of a parser diagnostic than a sema diagnostic?
+  if (!DS.isMissingDeclaratorOk()) {
+    // FIXME: This diagnostic is emitted even when various previous
+    // errors occurred (see e.g. test/Sema/decl-invalid.c). However,
+    // DeclSpec has no means of communicating this information, and the
+    // responsible parser functions are quite far apart.
+    Diag(DS.getSourceRange().getBegin(), diag::err_no_declarators)
+      << DS.getSourceRange();
+    return 0;
+  }
+
   return dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
 }
 

Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Sun Dec 28 09:28:59 2008
@@ -5,10 +5,12 @@
 template  x;            // expected-error {{expected '<' after 'template'}}
 export template x;      // expected-error {{expected '<' after 'template'}} \
                         // expected-note {{exported templates are unsupported}}
-template < ;            // expected-error {{parse error}}
-template <template X> ; // expected-error {{expected '<' after 'template'}}
-template <template <typename> > ;       // expected-error {{expected 'class' before '>'}}
-template <template <typename> Foo> ;    // expected-error {{expected 'class' before 'Foo'}}
+// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic. This is
+// because ParseNonTypeTemplateParameter starts parsing a DeclSpec.
+template < ;            // expected-error {{parse error}} expected-error {{declaration does not declare anything}}
+template <template X> struct Err1; // expected-error {{expected '<' after 'template'}}
+template <template <typename> > struct Err2;       // expected-error {{expected 'class' before '>'}}
+template <template <typename> Foo> struct Err3;    // expected-error {{expected 'class' before 'Foo'}}
 
 // Template function declarations
 template <typename T> void foo();

Modified: cfe/trunk/test/Sema/decl-invalid.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/decl-invalid.c?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/test/Sema/decl-invalid.c (original)
+++ cfe/trunk/test/Sema/decl-invalid.c Sun Dec 28 09:28:59 2008
@@ -1,6 +1,7 @@
 // RUN: clang %s -fsyntax-only -verify
 
-typedef union <anonymous> __mbstate_t;  // expected-error {{declaration of anonymous union must be a definition}}
+// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic
+typedef union <anonymous> __mbstate_t;  // expected-error {{declaration of anonymous union must be a definition}} expected-error {{declaration does not declare anything}}
 
 
 // PR2017
@@ -9,3 +10,9 @@
   int r[x()];  // expected-error {{size of array has non-integer type 'void'}}
 }
 
+int; // expected-error {{declaration does not declare anything}}
+typedef int; // expected-error {{declaration does not declare anything}}
+const int; // expected-error {{declaration does not declare anything}}
+struct; // expected-error {{declaration of anonymous struct must be a definition}} // expected-error {{declaration does not declare anything}}
+typedef int I;
+I; // expected-error {{declaration does not declare anything}}

Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=61454&r1=61453&r2=61454&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Sun Dec 28 09:28:59 2008
@@ -100,4 +100,8 @@
 void ogfn()
 {
   mutable int ml; // expected-error {{error: 'mutable' can only be applied to member variables}}
+
+  // PR3020: This used to crash due to double ownership of C4.
+  struct C4;
+  C4; // expected-error {{declaration does not declare anything}}
 }





More information about the cfe-commits mailing list