Skip to content

Commit

Permalink
Adopt a more principled approach to invalid declarations:
Browse files Browse the repository at this point in the history
  - If a declaration is an invalid redeclaration of an existing name,
    complain about the invalid redeclaration then avoid adding it to
    the AST (we can still parse the definition or initializer, if any).
  - If the declaration is invalid but there is no prior declaration
    with that name, introduce the invalid declaration into the AST
    (for later error recovery).
  - If the declaration is an invalid redeclaration of a builtin that
    starts with __builtin_, we produce an error and drop the
    redeclaration. If it is an invalid redeclaration of a library
    builtin (e.g., malloc, printf), warn (don't error!) and drop the
    redeclaration.

If a user attempts to define a builtin, produce an error and (if it's
a library builtin like malloc) suggest -ffreestanding.

This addresses <rdar://problem/6097585> and PR2892. However, PR3588 is
still going to cause some problems when builtins are redeclared
without a prototype.

llvm-svn: 64639
  • Loading branch information
DougGregor committed Feb 16, 2009
1 parent de39198 commit 75a45ba
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 92 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")
LIBBUILTIN(alloca, "v*z", "f:stdlib.h:")
LIBBUILTIN(calloc, "v*zz", "f:stdlib.h:")
LIBBUILTIN(malloc, "v*z", "f:stdlib.h:")
LIBBUILTIN(realloc, "v*v*z", "f:stdlib.h")
LIBBUILTIN(memcpy, "v*v*vC*z", "f:string.h:")
LIBBUILTIN(memmove, "v*v*vC*z", "f:string.h:")
LIBBUILTIN(memset, "v*v*iz", "f:string.h:")
Expand Down
10 changes: 9 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,17 @@ DIAG(ext_implicit_lib_function_decl, EXTWARN,
DIAG(note_please_include_header, NOTE,
"please include the header <%0> or explicitly provide a declaration for '%1'")
DIAG(note_previous_builtin_declaration, NOTE,
"%0 was implicitly declared here with type %1")
"%0 is a builtin with type %1")
DIAG(err_implicit_decl_requires_stdio, ERROR,
"implicit declaration of '%0' requires inclusion of the header <stdio.h>")
DIAG(warn_redecl_library_builtin, WARNING,
"incompatible redeclaration of library function %0 will be ignored")
DIAG(err_builtin_definition, ERROR,
"definition of builtin function %0")
DIAG(err_builtin_lib_definition, ERROR,
"definition of library function %0 in a hosted implementation")
DIAG(note_builtin_lib_def_freestanding, NOTE,
"use -ffreestanding to compile as a freestanding implementation")

/// parser diagnostics
DIAG(ext_typedef_without_a_name, EXTWARN,
Expand Down
19 changes: 10 additions & 9 deletions clang/lib/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,14 +282,16 @@ class Sema : public Action {
bool IsFunctionDefinition);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl* LastDeclarator,
Decl* PrevDecl, bool& InvalidDecl);
Decl* PrevDecl, bool& InvalidDecl,
bool &Redeclaration);
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl* LastDeclarator,
Decl* PrevDecl, bool& InvalidDecl);
QualType R, Decl* LastDeclarator,
Decl* PrevDecl, bool& InvalidDecl,
bool &Redeclaration);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl *LastDeclarator,
Decl* PrevDecl, bool IsFunctionDefinition,
bool& InvalidDecl);
bool& InvalidDecl, bool &Redeclaration);
virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D);
virtual void ActOnParamDefaultArgument(DeclTy *param,
SourceLocation EqualLoc,
Expand Down Expand Up @@ -395,11 +397,10 @@ class Sema : public Action {
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
Decl *LastDecl);
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old,
bool &Redeclaration);
VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
FunctionDecl *MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
bool MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
bool MergeVarDecl(VarDecl *New, Decl *Old);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
void CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD);

/// C++ Overloading.
Expand Down
Loading

0 comments on commit 75a45ba

Please sign in to comment.