Diagnose declarations that don't declare anything, and fix PR3020.
Examples: int; typedef int; llvm-svn: 61454
This commit is contained in:
parent
85cd7bac29
commit
a2b5e31cb1
|
@ -318,6 +318,10 @@ public:
|
|||
/// 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
|
||||
|
|
|
@ -313,3 +313,11 @@ void DeclSpec::Finish(Diagnostic &D, SourceManager& SrcMgr,
|
|||
// '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;
|
||||
}
|
||||
|
|
|
@ -302,7 +302,7 @@ public:
|
|||
|
||||
/// 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,
|
||||
|
|
|
@ -773,10 +773,17 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
|
|||
/// 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()));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,12 @@ export class foo { }; // expected-error {{expected template}}
|
|||
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();
|
||||
|
|
|
@ -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 a() {
|
|||
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}}
|
||||
|
|
|
@ -100,4 +100,8 @@ mutable void gfn(); // expected-error {{illegal storage class on function}}
|
|||
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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue