aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Builtins.def1
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.def10
-rw-r--r--lib/Sema/Sema.h19
-rw-r--r--lib/Sema/SemaDecl.cpp143
-rw-r--r--lib/Sema/SemaDeclCXX.cpp11
-rw-r--r--test/Sema/implicit-builtin-decl.c30
-rw-r--r--test/Sema/predefined-function.c4
-rw-r--r--test/Sema/tentative-decls.c10
-rw-r--r--test/Sema/typedef-redef.c10
-rw-r--r--test/SemaObjC/class-def-test-1.m6
10 files changed, 152 insertions, 92 deletions
diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def
index ed658b8d02..c9289ab4b3 100644
--- a/include/clang/AST/Builtins.def
+++ b/include/clang/AST/Builtins.def
@@ -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:")
diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def
index 570b711e07..cdb7f62d72 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.def
+++ b/include/clang/Basic/DiagnosticSemaKinds.def
@@ -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,
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 362d8dc02d..a96618f5a9 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -282,14 +282,16 @@ public:
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,
@@ -395,11 +397,10 @@ public:
/// 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.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a47094ecfe..3960a7d57c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -364,11 +364,13 @@ NamespaceDecl *Sema::GetStdNamespace() {
return StdNamespace;
}
-/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
-/// and scope as a previous declaration 'Old'. Figure out how to resolve this
-/// situation, merging decls or emitting diagnostics as appropriate.
+/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the
+/// same name and scope as a previous declaration 'Old'. Figure out
+/// how to resolve this situation, merging decls or emitting
+/// diagnostics as appropriate. Returns true if there was an error,
+/// false otherwise.
///
-TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
+bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
bool objc_types = false;
// Allow multiple definitions for ObjC built-in typedefs.
// FIXME: Verify the underlying types are equivalent!
@@ -387,19 +389,19 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
break;
Context.setObjCClassType(New);
objc_types = true;
- return New;
+ return false;
case 3:
if (!TypeID->isStr("SEL"))
break;
Context.setObjCSelType(New);
objc_types = true;
- return New;
+ return false;
case 8:
if (!TypeID->isStr("Protocol"))
break;
Context.setObjCProtoType(New->getUnderlyingType());
objc_types = true;
- return New;
+ return false;
}
// Fall through - the typedef name was not a builtin type.
}
@@ -410,7 +412,7 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
<< New->getDeclName();
if (!objc_types)
Diag(OldD->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
// Determine the "old" type we'll use for checking and diagnostics.
@@ -430,17 +432,17 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
<< New->getUnderlyingType() << OldType;
if (!objc_types)
Diag(Old->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
- if (objc_types) return New;
- if (getLangOptions().Microsoft) return New;
+ if (objc_types) return false;
+ if (getLangOptions().Microsoft) return false;
// C++ [dcl.typedef]p2:
// In a given non-class scope, a typedef specifier can be used to
// redefine the name of any type declared in that scope to refer
// to the type to which it already refers.
if (getLangOptions().CPlusPlus && !isa<CXXRecordDecl>(CurContext))
- return New;
+ return false;
// In C, redeclaration of a type is a constraint violation (6.7.2.3p1).
// Apparently GCC, Intel, and Sun all silently ignore the redeclaration if
@@ -450,14 +452,14 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
if (PP.getDiagnostics().getSuppressSystemWarnings()) {
SourceManager &SrcMgr = Context.getSourceManager();
if (SrcMgr.isInSystemHeader(Old->getLocation()))
- return New;
+ return false;
if (SrcMgr.isInSystemHeader(New->getLocation()))
- return New;
+ return false;
}
Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
/// DeclhasAttr - returns true if decl Declaration already has the target
@@ -494,25 +496,24 @@ static void MergeAttributes(Decl *New, Decl *Old) {
/// declarator D which has the same name and scope as a previous
/// declaration 'Old'. Figure out how to resolve this situation,
/// merging decls or emitting diagnostics as appropriate.
-/// Redeclaration will be set true if this New is a redeclaration OldD.
///
/// In C++, New and Old must be declarations that are not
/// overloaded. Use IsOverload to determine whether New and Old are
/// overloaded, and to select the Old declaration that New should be
/// merged with.
-FunctionDecl *
-Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
+///
+/// Returns true if there was an error, false otherwise.
+bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
assert(!isa<OverloadedFunctionDecl>(OldD) &&
"Cannot merge with an overloaded function declaration");
- Redeclaration = false;
// Verify the old decl was also a function.
FunctionDecl *Old = dyn_cast<FunctionDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
Diag(OldD->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
// Determine whether the previous declaration was a definition,
@@ -520,12 +521,9 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
diag::kind PrevDiag;
if (Old->isThisDeclarationADefinition())
PrevDiag = diag::note_previous_definition;
- else if (Old->isImplicit()) {
- if (Old->getBuiltinID(Context))
- PrevDiag = diag::note_previous_builtin_declaration;
- else
- PrevDiag = diag::note_previous_implicit_declaration;
- } else
+ else if (Old->isImplicit())
+ PrevDiag = diag::note_previous_implicit_declaration;
+ else
PrevDiag = diag::note_previous_declaration;
QualType OldQType = Context.getCanonicalType(Old->getType());
@@ -543,8 +541,7 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
if (OldReturnType != NewReturnType) {
Diag(New->getLocation(), diag::err_ovl_diff_return_type);
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
- Redeclaration = true;
- return New;
+ return true;
}
const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
@@ -556,7 +553,7 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
if (OldMethod->isStatic() || NewMethod->isStatic()) {
Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member);
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
- return New;
+ return true;
}
// C++ [class.mem]p1:
@@ -586,7 +583,6 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
if (OldQType == NewQType) {
// We have a redeclaration.
MergeAttributes(New, Old);
- Redeclaration = true;
return MergeCXXFunctionDecl(New, Old);
}
@@ -598,19 +594,30 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
if (!getLangOptions().CPlusPlus &&
Context.typesAreCompatible(OldQType, NewQType)) {
MergeAttributes(New, Old);
- Redeclaration = true;
- return New;
+ return false;
}
// A function that has already been declared has been redeclared or defined
// with a different type- show appropriate diagnostic
+ if (unsigned BuiltinID = Old->getBuiltinID(Context)) {
+ // The user has declared a builtin function with an incompatible
+ // signature.
+ if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
+ // The function the user is redeclaring is a library-defined
+ // function like 'malloc' or 'printf'. Warn about the
+ // redeclaration, then ignore it.
+ Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
+ Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
+ << Old << Old->getType();
+ return false;
+ }
+
+ PrevDiag = diag::note_previous_builtin_declaration;
+ }
- // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
- // TODO: This is totally simplistic. It should handle merging functions
- // together etc, merging extern int X; int X; ...
Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName();
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
- return New;
+ return true;
}
/// Predicate for C "tentative" external object definitions (C99 6.9.2).
@@ -671,14 +678,14 @@ void Sema::CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD) {
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
/// definitions here, since the initializer hasn't been attached.
///
-VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
+bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
// Verify the old decl was also a variable.
VarDecl *Old = dyn_cast<VarDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
Diag(OldD->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
MergeAttributes(New, Old);
@@ -689,7 +696,7 @@ VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
Diag(New->getLocation(), diag::err_redefinition_different_type)
<< New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
New->setType(MergedT);
// C99 6.2.2p4: Check if we have a static decl followed by a non-static.
@@ -698,21 +705,22 @@ VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
Old->getStorageClass() == VarDecl::Extern)) {
Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
// C99 6.2.2p4: Check if we have a non-static decl followed by a static.
if (New->getStorageClass() != VarDecl::Static &&
Old->getStorageClass() == VarDecl::Static) {
Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return New;
+ return true;
}
// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
if (New->getStorageClass() != VarDecl::Extern && !New->isFileVarDecl()) {
Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
+ return true;
}
- return New;
+ return false;
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
@@ -1245,7 +1253,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
NamedDecl *PrevDecl;
NamedDecl *New;
bool InvalidDecl = false;
-
+
// See if this is a redefinition of a variable in the same scope.
if (!D.getCXXScopeSpec().isSet() && !D.getCXXScopeSpec().isInvalid()) {
DC = CurContext;
@@ -1315,15 +1323,17 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
QualType R = GetTypeForDeclarator(D, S);
assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
+ bool Redeclaration = false;
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
New = ActOnTypedefDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
- InvalidDecl);
+ InvalidDecl, Redeclaration);
} else if (R.getTypePtr()->isFunctionType()) {
New = ActOnFunctionDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
- IsFunctionDefinition, InvalidDecl);
+ IsFunctionDefinition, InvalidDecl,
+ Redeclaration);
} else {
New = ActOnVariableDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
- InvalidDecl);
+ InvalidDecl, Redeclaration);
}
if (New == 0)
@@ -1333,8 +1343,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
- // If this has an identifier, add it to the scope stack.
- if (Name)
+ // If this has an identifier and is not an invalid redeclaration,
+ // add it to the scope stack.
+ if (Name && !(Redeclaration && InvalidDecl))
PushOnScopeChains(New, S);
// If any semantic error occurred, mark the decl as invalid.
if (D.getInvalidType() || InvalidDecl)
@@ -1346,7 +1357,8 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
NamedDecl*
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl* LastDeclarator,
- Decl* PrevDecl, bool& InvalidDecl) {
+ Decl* PrevDecl, bool& InvalidDecl,
+ bool &Redeclaration) {
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
if (D.getCXXScopeSpec().isSet()) {
Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
@@ -1368,8 +1380,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
- NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
- if (NewTD == 0) return 0;
+ Redeclaration = true;
+ if (MergeTypeDefDecl(NewTD, PrevDecl))
+ InvalidDecl = true;
}
if (S->getFnParent() == 0) {
@@ -1390,7 +1403,8 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NamedDecl*
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl* LastDeclarator,
- Decl* PrevDecl, bool& InvalidDecl) {
+ Decl* PrevDecl, bool& InvalidDecl,
+ bool &Redeclaration) {
DeclarationName Name = GetNameForDeclarator(D);
// Check that there are no default arguments (C++ only).
@@ -1483,8 +1497,9 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
return 0;
}
- NewVD = MergeVarDecl(NewVD, PrevDecl);
- if (NewVD == 0) return 0;
+ Redeclaration = true;
+ if (MergeVarDecl(NewVD, PrevDecl))
+ InvalidDecl = true;
if (D.getCXXScopeSpec().isSet()) {
// No previous declaration in the qualifying scope.
@@ -1500,7 +1515,7 @@ NamedDecl*
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl *LastDeclarator,
Decl* PrevDecl, bool IsFunctionDefinition,
- bool& InvalidDecl) {
+ bool& InvalidDecl, bool &Redeclaration) {
assert(R.getTypePtr()->isFunctionType());
DeclarationName Name = GetNameForDeclarator(D);
@@ -1691,7 +1706,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Merge the decl with the existing one if appropriate. Since C functions
// are in a flat namespace, make sure we consider decls in outer scopes.
bool OverloadableAttrRequired = false;
- bool Redeclaration = false;
if (PrevDecl &&
(!getLangOptions().CPlusPlus||isDeclInScope(PrevDecl, DC, S))) {
// Determine whether NewFD is an overload of PrevDecl or
@@ -1706,6 +1720,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (!AllowOverloadingOfFunction(PrevDecl, Context) ||
!IsOverload(NewFD, PrevDecl, MatchedDecl)) {
+ Redeclaration = true;
Decl *OldDecl = PrevDecl;
// If PrevDecl was an overloaded function, extract the
@@ -1715,10 +1730,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// NewFD and PrevDecl represent declarations that need to be
// merged.
- NewFD = MergeFunctionDecl(NewFD, OldDecl, Redeclaration);
+ if (MergeFunctionDecl(NewFD, OldDecl))
+ InvalidDecl = true;
- if (NewFD == 0) return 0;
- if (Redeclaration) {
+ if (!InvalidDecl) {
NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
// An out-of-line member function declaration must also be a
@@ -2734,6 +2749,16 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
Diag(Definition->getLocation(), diag::note_previous_definition);
}
+ // Builtin functions cannot be defined.
+ if (unsigned BuiltinID = FD->getBuiltinID(Context)) {
+ if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
+ Diag(FD->getLocation(), diag::err_builtin_lib_definition) << FD;
+ Diag(FD->getLocation(), diag::note_builtin_lib_def_freestanding);
+ } else
+ Diag(FD->getLocation(), diag::err_builtin_definition) << FD;
+ FD->setInvalidDecl();
+ }
+
PushDeclContext(FnBodyScope, FD);
// Check the validity of our function parameters
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 02c2e9bbfa..4af8cc030b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -201,9 +201,11 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
// MergeCXXFunctionDecl - Merge two declarations of the same C++
// function, once we already know that they have the same
-// type. Subroutine of MergeFunctionDecl.
-FunctionDecl *
-Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
+// type. Subroutine of MergeFunctionDecl. Returns true if there was an
+// error, false otherwise.
+bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
+ bool Invalid = false;
+
// C++ [dcl.fct.default]p4:
//
// For non-template functions, default arguments can be added in
@@ -226,13 +228,14 @@ Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
diag::err_param_default_argument_redefinition)
<< NewParam->getDefaultArg()->getSourceRange();
Diag(OldParam->getLocation(), diag::note_previous_definition);
+ Invalid = true;
} else if (OldParam->getDefaultArg()) {
// Merge the old default argument into the new parameter
NewParam->setDefaultArg(OldParam->getDefaultArg());
}
}
- return New;
+ return Invalid;
}
/// CheckCXXDefaultArguments - Verify that the default arguments for a
diff --git a/test/Sema/implicit-builtin-decl.c b/test/Sema/implicit-builtin-decl.c
index e9b0556f3e..892e372eff 100644
--- a/test/Sema/implicit-builtin-decl.c
+++ b/test/Sema/implicit-builtin-decl.c
@@ -2,13 +2,13 @@
void f() {
int *ptr = malloc(sizeof(int) * 10); // expected-warning{{implicitly declaring C library function 'malloc' with type}} \
// expected-note{{please include the header <stdlib.h> or explicitly provide a declaration for 'malloc'}} \
- // expected-note{{'malloc' was implicitly declared here with type 'void *}}
+ // expected-note{{'malloc' is a builtin with type 'void *}}
}
void *alloca(__SIZE_TYPE__); // redeclaration okay
-int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-error{{conflicting types for 'calloc'}} \
- // expected-note{{'calloc' was implicitly declared here with type 'void *}}
+int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-warning{{incompatible redeclaration of library function 'calloc' will be ignored}} \
+ // expected-note{{'calloc' is a builtin with type 'void *}}
void g(int malloc) { // okay: these aren't functions
@@ -16,11 +16,29 @@ void g(int malloc) { // okay: these aren't functions
}
void h() {
- int malloc(int); // expected-error{{conflicting types for 'malloc'}}
- int strcpy(int); // expected-error{{conflicting types for 'strcpy'}} \
- // expected-note{{'strcpy' was implicitly declared here with type 'char *(char *, char const *)'}}
+ int malloc(int); // expected-warning{{incompatible redeclaration of library function 'malloc' will be ignored}}
+ int strcpy(int); // expected-warning{{incompatible redeclaration of library function 'strcpy' will be ignored}} \
+ // expected-note{{'strcpy' is a builtin with type 'char *(char *, char const *)'}}
}
void f2() {
fprintf(0, "foo"); // expected-error{{implicit declaration of 'fprintf' requires inclusion of the header <stdio.h>}}
}
+
+// PR2892
+void __builtin_object_size(); // expected-error{{conflicting types}} \
+// expected-note{{'__builtin_object_size' is a builtin with type}}
+
+int a[10];
+
+int f0() {
+ return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
+}
+
+void * realloc(void *p, int size) { // expected-warning{{incompatible redeclaration of library function 'realloc' will be ignored}} \
+// expected-note{{'realloc' is a builtin with type 'void *(void *, unsigned long)'}} \
+// expected-error{{definition of library function 'realloc' in a hosted implementation}} \
+ // expected-note{{use -ffreestanding to compile as a freestanding implementation}}
+ return p;
+}
+
diff --git a/test/Sema/predefined-function.c b/test/Sema/predefined-function.c
index 2a254cceb7..bce63550cc 100644
--- a/test/Sema/predefined-function.c
+++ b/test/Sema/predefined-function.c
@@ -11,7 +11,7 @@ int foo();
int foo()
{
int eli(int (int)); // expected-error {{conflicting types for 'eli'}}
- eli(b);
+ eli(b); // expected-error{{incompatible type passing}}
return 0;
}
@@ -25,13 +25,11 @@ int bar() // expected-error {{redefinition of 'bar'}}
return 0;
}
-#if 0
int foobar(int); // note {{previous declaration is here}}
int foobar() // error {{conflicting types for 'foobar'}}
{
return 0;
}
-#endif
int wibble(); // expected-note {{previous declaration is here}}
float wibble() // expected-error {{conflicting types for 'wibble'}}
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
index 0e4b13a843..12ce181e0f 100644
--- a/test/Sema/tentative-decls.c
+++ b/test/Sema/tentative-decls.c
@@ -1,4 +1,4 @@
-// RUN: clang %s -verify -fsyntax-only
+// RUN: clang %s -fsyntax-only -verify
const int a [1] = {1};
extern const int a[];
@@ -10,12 +10,14 @@ extern const int c[] = {1}; // expected-warning{{'extern' variable has an initia
const int c[];
int i1 = 1; // expected-note {{previous definition is here}}
-int i1 = 2; // expected-error {{redefinition of 'i1'}} // expected-note {{previous definition is here}}
+int i1 = 2; // expected-error {{redefinition of 'i1'}}
int i1;
int i1;
extern int i1; // expected-note {{previous definition is here}}
-static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}} expected-note {{previous definition is here}}
-int i1 = 3; // expected-error{{redefinition of 'i1'}} expected-error{{non-static declaration of 'i1' follows static declaration}}
+static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}}
+
+static int i2 = 5; // expected-note 2 {{previous definition is here}}
+int i2 = 3; // expected-error{{redefinition of 'i2'}} expected-error{{non-static declaration of 'i2' follows static declaration}}
__private_extern__ int pExtern;
int pExtern = 0;
diff --git a/test/Sema/typedef-redef.c b/test/Sema/typedef-redef.c
index d6962f1cd1..48c4863513 100644
--- a/test/Sema/typedef-redef.c
+++ b/test/Sema/typedef-redef.c
@@ -1,4 +1,4 @@
-// RUN: clang < %s -fsyntax-only -verify
+// RUN: clang -fsyntax-only -verify %s
// size_t coming from a system header.
#include <stddef.h>
@@ -7,7 +7,11 @@ typedef __SIZE_TYPE__ size_t;
typedef const int x; // expected-note {{previous definition is here}}
-extern x a; // expected-note {{previous definition is here}}
+extern x a;
typedef int x; // expected-error {{typedef redefinition with different types}}
-extern x a; // expected-error{{redefinition of 'a' with a different type}}
+extern x a;
+// <rdar://problem/6097585>
+int y; // expected-note 2 {{previous definition is here}}
+float y; // expected-error{{redefinition of 'y' with a different type}}
+double y; // expected-error{{redefinition of 'y' with a different type}}
diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m
index 50493f1b86..2c625fa0bc 100644
--- a/test/SemaObjC/class-def-test-1.m
+++ b/test/SemaObjC/class-def-test-1.m
@@ -14,10 +14,10 @@ typedef int INTF; // expected-note {{previous definition is here}}
@interface INTF1 : OBJECT @end // expected-error {{duplicate interface definition for class 'INTF1'}}
-typedef int OBJECT; // expected-note {{previous definition is here}} \
- expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
+typedef int OBJECT; // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
-@interface INTF2 : OBJECT @end // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
+typedef int OBJECT2; // expected-note {{previous definition is here}}
+@interface INTF2 : OBJECT2 @end // expected-error {{redefinition of 'OBJECT2' as different kind of symbol}}
@protocol PROTO;