[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