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,
|
/// things like "_Imaginary" (lacking an FP type). After calling this method,
|
||||||
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
|
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
|
||||||
void Finish(Diagnostic &D, SourceManager& SrcMgr, const LangOptions &Lang);
|
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
|
/// 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'?
|
// '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;
|
||||||
|
}
|
||||||
|
|
|
@ -773,9 +773,16 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
|
||||||
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
|
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
|
||||||
/// no declarator (e.g. "struct foo;") is parsed.
|
/// no declarator (e.g. "struct foo;") is parsed.
|
||||||
Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
||||||
// TODO: emit error on 'int;' or 'const enum foo;'.
|
// FIXME: Isn't that more of a parser diagnostic than a sema diagnostic?
|
||||||
// TODO: emit error on 'typedef int;'
|
if (!DS.isMissingDeclaratorOk()) {
|
||||||
// if (!DS.isMissingDeclaratorOk()) Diag(...);
|
// 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()));
|
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'}}
|
template x; // expected-error {{expected '<' after 'template'}}
|
||||||
export template x; // expected-error {{expected '<' after 'template'}} \
|
export template x; // expected-error {{expected '<' after 'template'}} \
|
||||||
// expected-note {{exported templates are unsupported}}
|
// expected-note {{exported templates are unsupported}}
|
||||||
template < ; // expected-error {{parse error}}
|
// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic. This is
|
||||||
template <template X> ; // expected-error {{expected '<' after 'template'}}
|
// because ParseNonTypeTemplateParameter starts parsing a DeclSpec.
|
||||||
template <template <typename> > ; // expected-error {{expected 'class' before '>'}}
|
template < ; // expected-error {{parse error}} expected-error {{declaration does not declare anything}}
|
||||||
template <template <typename> Foo> ; // expected-error {{expected 'class' before 'Foo'}}
|
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 function declarations
|
||||||
template <typename T> void foo();
|
template <typename T> void foo();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// RUN: clang %s -fsyntax-only -verify
|
// 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
|
// PR2017
|
||||||
|
@ -9,3 +10,9 @@ int a() {
|
||||||
int r[x()]; // expected-error {{size of array has non-integer type 'void'}}
|
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()
|
void ogfn()
|
||||||
{
|
{
|
||||||
mutable int ml; // expected-error {{error: 'mutable' can only be applied to member variables}}
|
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